2013-12-13 5 views
2

У меня есть эта маленькая проблема, и я хочу, чтобы выяснить, whay это происходит со мной: Я сделал класс вроде этого:ява объявление класса с отключением метода общего типа возвращающегося другой общего типа

public class SomeSimpleClass { 
    //and I had method who returns generic. it can be instance of whatever, and for sure can be casted to U: 
    public <U>U giveMeSomething(String arg) { 
     return (U)SomewhereSomething.getValueCastingIsOK(arg); 
    } 
} 

и затем Я использую это так:

// give me some number: 
Integer number = instanceSomeSimpleClass.giveMeSomething("I want integer value"); 

ИЛИ

String text = instanceSomeSimpleClass.giveMeSomething("I want text now"); 

и эв все в порядке. getValueCastingIsOK из SomewhereSomething возвращает мне то, что я хочу, и мне не нужно вводить тип в giveMeSomething. Похоже, U заменяется типом из ассоциативного переменной .. и все это круто ..

НО затем создать новый класс:

public class SomeOtherClass <T extends Something> { 
    //And I have the exactly same method here: 
    public <U>U giveMeSomething(String arg) { 
     return (U)SomewhereSomething.getValueCastingIsOK(arg); 
    } 
} 

и теперь, когда я хочу, чтобы использовать его в Точно так же компилятор (я использую Java 1.7) говорит мне, что мне нужно использовать typecast и начинаю использовать giveMeSomething, как это, потому что U теперь объект, и ничего больше ...

Integer number = (Integer)instanceSomeSimpleClass.giveMeSomething("I want integer value"); 

:(

Почему во втором случае компилятор не может получить тип U таким же образом, как в первом случае. И что я должен делать, чтобы так?

Поблагодарите в течение ответы, предложения ..;)

+0

Да? Что такое 'U'? – SLaks

+0

Извините, я забыл .. Объявление: public U giveMeSomething (String arg) – mmmika

+0

Используете ли вы тип raw 'SomeOtherClass'? – rgettman

ответ

1

Проблема в том, что вы используете необработанный тип класса SomeOtherClass, но не питая никаких параметров типа в вашем объявлении:

SomeOtherClass instanceSomeSimpleClass = new SomeOtherClass(); 

Когда вы это сделаете, компилятор Java заменит ВСЕ дженерики в классе версией стирания типа, даже несвязанные дженерики, такие как ваш общий метод. Типа стирание метода

public <U>U giveMeSomething(String arg) { 

становится

public Object giveMeSomething(String arg) { 

, который требует приведения к Integer.

Вы должны либо указать параметр типа для SomeOtherClass (бесполезно, если вы не устранен ненужного кода, который использует T размещать код класса здесь):

SomeOtherClass<Something> instanceSomeSimpleClass = new SomeOtherClass<Something>(); 

Или вы можете удалить параметр типа на определение класса, как вы имели его первоначально:

public class SomeSimpleClass { 

Либо будет держать общий метод нетронутыми и устранить необходимость бросить возвращаемый тип giveMeSomething.

+0

Фактически это не совсем так. Просто частично. Я сделал тест, где я указал только общий U, и это работает. Я пробовал что-то вроде этого: public U giveMeSomething (String arg), и это было нормально для типа возвращаемого String, а не для Integer точно. Итак, похоже, что любая специализация любого родового типа включается общее отображение и отключить объекты по умолчанию, как вы правы, в этом случае. Теперь просто чтобы узнать, как я могу сделать трюк, чтобы переключить его во время компилятора, не разрушая основной код скелета :) – mmmika

1

Вы упускаете синтаксис Java для явного ввода:

public <U>U giveMeSomething(String arg) { 
    return SomewhereSomething.<U>getValueCastingIsOK(arg); 
} 

Обратите внимание на <U> между точкой и именем метода. Обратите внимание также, что теперь литье не требуется.

Вот как вы явно объявляете, что тип для типизированного метода. Без этого java должен вывести тип, которого он не может здесь, поэтому (небезопасное) литье не требуется.

Другой пример для иллюстрации. В этом случае, Java может определить тип является Integer из вида, что результат быть назначен:

Integer number = instanceSomeSimpleClass.giveMeSomething("I want integer value"); 

Но если вы должны были использовать значение без назначения его, вам нужно пройти, чтобы напечатать :

someIntegerRequired(instanceSomeSimpleClass.<Integer>giveMeSomething("I want integer value")); 
+0

Спасибо, SomewhereSomething. getValueCastingIsOK (arg); всплывает проблема в другую ответственность. Но поскольку это закрытый объект библиотеки, я ничего не могу с этим поделать. Тип U задается типом ассоциатора, и если мы не передадим эту информацию компилятору, он будет работать так же, как и объект супер-типа. (Без ассоциации будет проглочен JVM). Но без экслизированного ввода SomeOtherClass, когда вы создаете экземпляр instanceSomeSimpleClass, вы не можете использовать giveMeSomething() без кастинга. Это была проблема – mmmika

 Смежные вопросы

  • Нет связанных вопросов^_^