2015-05-05 79 views
3

编辑: 要清楚我不问在java中如何做枚举。我在问java中是否存在与Enums中的Swifts关联值互补的东西。这不仅仅是我如何将值存储在枚举上。看看我提供的例子,你会看到不同之处。如何使用像Swift枚举这样的关联值创建Java枚举?

因此,iOS开发人员向我展示了他使用swifts enum关联值的体系结构。这个概念对我来说似乎很有趣,作为一名android开发人员,我很好奇,看看它是否可以在java中使用,而不会过于冗长。什么是Java枚举的等价物?还是不可能?

这里是我的意思是关联值的例子。它的形式为apple docs.

enum Barcode { 
    case UPCA(Int, Int, Int, Int) 
    case QRCode(String) 
} 

// Instantiated 
var productBarcode = Barcode.UPCA(8, 85909, 51226, 3) 
// or 
productBarcode = .QRCode("ABCDEFGHIJKLMNOP") 


switch productBarcode { 
case .UPCA(let numberSystem, let manufacturer, let product, let check): 
    println("UPC-A: \(numberSystem), \(manufacturer), \(product), \(check).") 
case .QRCode(let productCode): 
    println("QR code: \(productCode).") 
} 
+0

我觉得'Pair '可能就是你要找的东西。为了给一个带有语义含义的名字,可能会提供一个'BarCodeEntry ',它提供一个'BarCode getBarCode()'和'T getData()'? –

+1

@chrylis你链接到的东西不是一回事。看看switch语句。注意let表达式的集合。在Java中,我不知道如何动态地让每个值具有不同的一组关联值,每个关联值具有不同的一组类型。你链接的文件根本就没有解释。 – startoftext

+0

@chrylis没有读到这个问题。我有同样的问题,发现这个问答很有用。 – rmp251

回答

6

对于我来说Java enums是不可能的。

为了贴近您发布的片段,您将会变得冗长,正如您已经假设的那样。

枚举

enum BarcodeType { 
    UPCA, 
    QRCode, 
    UNDEFINED; 
} 

工厂类

abstract class Barcode { 

    abstract public BarcodeType getType(); 

    public static final Barcode newUPCA(int numberSystem, int manufacturer, int product, int check) { 
     return new BarcodeUPCA(numberSystem, manufacturer, product, check); 
    } 

    public static final Barcode newQRCode(String productCode) { 
     return new BarcodeQRCode(productCode); 
    } 
} 

具体实施UPCA

class BarcodeUPCA extends Barcode { 
    private final int numberSystem; 
    private final int manufacturer; 
    private final int product; 
    private final int check; 

    public BarcodeUPCA(int numberSystem, int manufacturer, int product, int check) { 
     this.numberSystem = numberSystem; 
     this.manufacturer = manufacturer; 
     this.product = product; 
     this.check = check; 
    } 

    public int getNumberSystem() { 
     return numberSystem; 
    } 

    public int getManufacturer() { 
     return manufacturer; 
    } 

    public int getProduct() { 
     return product; 
    } 

    public int getCheck() { 
     return check; 
    } 

    @Override 
    public BarcodeType getType() { 
     return BarcodeType.UPCA; 
    } 
} 

具体实施QR码

class BarcodeQRCode extends Barcode { 

    private final String productCode; 

    public BarcodeQRCode(String productCode) { 
     this.productCode = productCode; 
    } 

    public String getProductCode() { 
     return productCode; 
    } 

    @Override 
    public BarcodeType getType() { 
     return BarcodeType.QRCode; 
    } 
} 

演示应用

public class BarcodeMain { 

    public static void main(String[] args) throws Exception { 
     List<Barcode> barcodes = new ArrayList<>(); 
     barcodes.add(Barcode.newUPCA(8, 85909, 51226, 3)); 
     barcodes.add(Barcode.newQRCode("foobar")); 

     for (Barcode barcode : barcodes) { 
      switch (barcode.getType()) { 
       case UPCA: { 
        BarcodeUPCA b = (BarcodeUPCA) barcode; 
        System.out.printf("UPC-A: %d, %d, %d, %d%n", 
          b.getNumberSystem(), 
          b.getManufacturer(), 
          b.getProduct(), 
          b.getCheck() 
        ); 
        break; 
       } 
       case QRCode: { 
        BarcodeQRCode b = (BarcodeQRCode) barcode; 
        System.out.printf("QR code: %s%n", b.getProductCode()); 
        break; 
       } 
       default: 
        System.err.println("unhandled type: " + barcode.getType()); 
      } 
     } 
} 

输出

UPC-A: 8, 85909, 51226, 3 
QR code: foobar 
2

我也挣扎着这个问题,有以下解决方案上来。值得注意的是,我甚至不使用枚举,因为Java的枚举不适合执行任务。重要的是,你需要类似switch的行为,并且每种情况下都有相关的值。

枚举样型

public abstract class Barcode 
{ 
    private Barcode() {} 

    void caseUPCA(IntFunction<IntFunction<IntFunction<IntConsumer>>> action) {} 
    void caseQRCode(Consumer<String> action) {} 

    static Barcode UPCA(int numberSystem, int manufacturer, int product, int check) 
    { 
     return new Barcode() 
     { 
      @Override public void caseUPCA(IntFunction<IntFunction<IntFunction<IntConsumer>>> action) 
      { 
       action.apply(numberSystem).apply(manufacturer).apply(product).accept(check); 
      } 
     }; 
    } 

    static Barcode QRCode(String text) 
    { 
     return new Barcode() 
     { 
      @Override public void caseQRCode(Consumer<String> action) 
      { 
       action.accept(text); 
      } 
     }; 
    } 
} 

演示应用程序

public class BarcodeMain 
{ 
    public static void main(String[] args) throws Exception 
    { 
     List<Barcode> barcodes = new ArrayList<>(); 
     barcodes.add(Barcode.UPCA(8, 85909, 51226, 3)); 
     barcodes.add(Barcode.QRCode("foobar")); 

     for(Barcode barcode: barcodes) 
     { 
      barcode.caseUPCA(numberSystem -> manufacturer -> product -> check -> 
       System.out.printf("UPC-A: %d, %d, %d, %d%n", numberSystem, manufacturer, product, check)); 
      barcode.caseQRCode(productCode -> 
       System.out.printf("QR code: %s%n", productCode)); 
     } 
    } 
} 

输出

UPC-A: 8, 85909, 51226, 3 
QR code: foobar 

个利弊

  • 实现代码比基于枚举的解决方案要少得多
  • 即使代码在使用现场比基于枚举的解决方案

利弊

  • 地段在Barcode实现中的尴尬嵌套。只是Java很丑。
  • 您不能从交换机案例操作中抛出异常。
  • UPCA实现中的角度盲点失明,因为有很多参数。为防止此漏入API,您可以声明public interface UPCAConsumer extends IntFunction<IntFunction<IntFunction<IntConsumer>>> {},并使用UPCAConsumer作为caseUPCA(action)参数类型。