java类声明与泛型类型disable方法返回另一个泛型类型

时间:2013-12-13 18:31:37

标签: java class generics declaration subtype

我有这个小问题,我想知道发生了什么事情发生在我身上: 我做了这样的课:

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");

OR

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

一切都好。来自SomewhereSomething的getValueCastingIsOK返回我想要的东西,而且我不需要在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)告诉我,我必须使用类型转换,并开始使用这样的giveMeSomething,因为U现在是对象,没有别的......

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

:(

为什么在第二种情况下,编译器无法以相同的方式获取U类型,如第一种情况。而我必须做的就是这样做?

感谢答案,建议..;)

2 个答案:

答案 0 :(得分: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>();

或者你可以删除类定义中的type参数,就像你原来的那样:

public class SomeSimpleClass {

要么保持泛型方法的完整性,又无需转换giveMeSomething的返回类型。

答案 1 :(得分: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"));