2016-10-25 14 views
0

Я портирование моего Java приложения от 1,6 до 1,8, а компилятор недоволен методами getAbstractTransactionCriteria() в следующем коде:Java 1,6 -> 1,8, то же стирание ошибки компиляция

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?

ответ

0

Если вы можете изменить прототипы функций, и аргументы не используются, кроме как для определения типа возврата, будет ли следующая работа для вас?

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

В качестве альтернативы вы можете использовать разные имена функций и не принимать аргументы. Например,

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

Итак, перейдите в фиктивную транзакцию/TemplateTransaction? Да, я мог бы это сделать. Однако это кажется немного неуклюжим. Нельзя ли делать то, что я делал? – skiaddict1

+0

Однако, что мне делать с абстрактными классами? Неужели нет способа делать то, что я делал? Я действительно не хочу составлять ложно разные имена, чтобы обойти проклятый компилятор. Разве такой полиморфизм больше не разрешен? – skiaddict1

+0

@ skiaddict1, это подтверждает меня даже тем, что этот подход разрешен в java 1.6, поскольку из моего понимания нет способа добиться полиморфизма на основе аргументов genericType. Общее обходное решение, которое я часто использую при решении одной и той же проблемы, - это использование дженериков в качестве аргументов (например, в моем ответе). Я надеюсь, что это поможет вам в дальнейшем, иначе вам нужно будет либо добавить дополнительный аргумент (например, тип Integer) для каждого полиморфного метода. Или используйте экземпляр статического места для каждого метода вместо класса. – n247s

1

Почему бы не использовать дженерики для этого? Примерно так:

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

Таким образом, вам нужен только один метод. Теперь мне известно, что оба метода могут быть совершенно разными (контент мудрый). Хотя даже вы можете просто проверить пройденный тип аргумента и соответственно выполнить действия.

Edit:
Я упомянул статическую PlaceHolder для поддержки полиморфизма. В принципе, если вы видите оба подхода выше, один запрашивает объект класса, а другой запрашивает экземпляр (обычно менее идеальный, так как вы вызываете этот метод для создания экземпляра, а не для одного).

Если вы не хотите использовать 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); 

Как вы можете видеть, таким образом, это своего рода можно использовать ваш «старый макет. Хотя, если это единственный способ, я бы defenitly посоветовал вам перепроектировать ваш текущий шаблон, так как его defenitly не идеально. (как упоминалось ранее, вы можете рассмотреть возможность использования разных имен для каждого метода, так как они возвращают разные результаты, чем предлагает их метод в этом случае)

+0

А, я понимаю, что вы имеете в виду сейчас, спасибо за то, что вы показываете мне время. К сожалению, это не сработает, потому что иногда этот шаблон использует такие вещи, как 'java.sql.Date' :-(Как уже упоминалось выше, я не согласен с тем, что я должен использовать разные имена для каждого метода. Оба они возвращают' AbstractTransactionCriteria', это имеет смысл называть их такими. В других местах я делаю то же самое с различными формами дат, почему «getDatejavasqlDate (...)» и «getDateMyCriteriaDate (...)»? Yuck! Мне придется исследовать полиморфизм в этой новой Java.Я снова откликнусь. Спасибо еще раз. – skiaddict1

+0

@ skiaddict1 В качестве аргумента против вашего утверждения, не имеющего разных имен методов, я бы сказал, что нет необходимости переполнять методы, поскольку вы знаете разницу перед вызовом (например, есть no genericType, участвующий в каком-либо методе или классе). Более конкретно, вам (придется) передать тип, поэтому почему бы не использовать разные имена для решения этой проблемы простой (чистый) способ? Хотя он может выглядеть более чистым с первого взгляда, для этого в java и беспорядочно запутались. – n247s

+0

извинения за то, что вы не отметили свой ответ как правильный, я бы хотел отметить оба, но не был допущен! Я поддержал его, как все, что мог. Еще раз спасибо за вашу помощь. – skiaddict1