Java 1.6 - > 1.8,相同的擦除编译错误

时间:2016-10-25 05:32:08

标签: java polymorphism erasure

我将我的Java应用程序从1.6移植到1.8,并且编译器对以下代码中的方法getAbstractTransactionCriteria()不满意:

public abstract class AbstractTransaction ...
public class TemplateTransaction extends AbstractTransaction ...
public class Transaction extends AbstractTransaction ...

abstract class AbstractTransactionCriteria {...}
class TransactionCriteria extends AbstractTransactionCriteria {...}
class TemplateCriteria extends AbstractTransactionCriteria {...}

TransactionCriteria getAbstractTransactionCriteria(Class<Transaction> c) {...}
TemplateCriteria    getAbstractTransactionCriteria(Class<TemplateTransaction> c) {...}

编译器告诉我两个方法具有相同的擦除,我可以接受,因为我在别处看到尖括号内的东西被编译器替换为Object

参数c仅用于实现多态性(它们未在方法体中使用),而这在Java 1.6中完全有效。

我应该怎样做才能在1.8中获得相同的结果?

2 个答案:

答案 0 :(得分:1)

为什么不使用泛型呢?喜欢这样的东西:

 public <T extends AbstractTransactionCriteria> T getAbstractTransactionCriteria(Class<T> c) {}
 // or
 public <T extends AbstractTransactionCriteria> T getAbstractTransactionCriteria(T t) {}

这样你只需要一种方法。现在我知道这两种方法可能完全不同(内容明智)。虽然你可以简单地检查传入的参数类型,然后相应地执行操作。

修改:
我提到了一个静态placeHolder来支持多态。 基本上,如果你看到上面的两个approuches,一个问一个Class对象,而另一个请求一个实例(通常不太理想,因为你调用这个方法来创建一个实例,而不是传递一个实例)。

如果你不想使用如上所述的genericTypes,你也可以选择这样做:

 abstract class AbstractTransactionCriteria {...}

 // SubClass layout
 class TransactionCriteria extends AbstractTransactionCriteria {
     // dummy instance doing nothing.
     public static final TransactionCriteria type = new TransactionCriteria();
 }

 class TemplateCriteria extends AbstractTransactionCriteria {
     // dummy instance doing nothing.
     public static final TemplateCriteria type = new TemplateCriteria ();
 }



 // method layout
 TransactionCriteria getAbstractTransactionCriteria(TransactionCriteria t)
 {...}

 TemplateCriteria getAbstractTransactionCriteria(TemplateCriteria  t)
 {...}


 // Call methods
 TransactionCriteria transaction = getAbstractTransactionCriteria(TransactionCriteria.type);
 TemplateCriteria transaction = getAbstractTransactionCriteria(TemplateCriteria.type);

正如您所看到的,通过这种方式,您可以使用您的旧版&#39;布局。虽然如果这是唯一的方法,我会默默地建议你重新设计你当前的模式,因为它的defenitly不理想。 (如前所述,您可能需要考虑为每个方法使用不同的名称,因为它们返回的结果与此方法中的方法名称建议不同)

答案 1 :(得分:0)

如果您可以自由更改函数原型,并且除了确定返回类型之外不使用参数,那么下面的内容是否适用于您?

TransactionCriteria getAbstractTransactionCriteria(Transaction c) {...}
TemplateCriteria    getAbstractTransactionCriteria(TemplateTransaction c) {...}

或者,您可以使用不同的函数名称并使它们不带参数。例如

TransactionCriteria getAbstractTransactionCriteria() {...}
TemplateCriteria    getAbstractTemplateCriteria() {...}