我使用的是Oracle JDK 7u79。我不知道为什么下面的代码会产生编译错误:
package generics;
import java.util.Collection;
import java.util.Collections;
class SomeClass {
public Collection<String> getStringCollection() {
return Collections.singleton("hello");
}
}
class SomeTypedClass<T> {
public Collection<String> getStringCollection() {
return Collections.singleton("hello");
}
}
public class SomeTest {
public static void main(String[] args) {
final int length1 = new SomeClass() .getStringCollection().iterator().next().length();
final int length2 = new SomeTypedClass().getStringCollection().iterator().next().length(); // compilation error
}
}
错误:
Error:(21, 89) java: cannot find symbol
symbol: method length()
location: class java.lang.Object
我已将常量泛型类型Collection<String>
指定为getStringCollection()
的方法参数,因此我认为SomeClass
和SomeTypedClass
都应该编译而不会出错。
为什么会这样?什么是正确的解决方案,即在不进行投射的情况下不断输入Collection
?
答案 0 :(得分:2)
实际上,由于您的SomeTypedClass<T>
期望传入的类型为T
,即使它未使用该类型,您也需要在SomeTest
中执行此操作:
public class SomeTest {
public static void main(String[] args) {
final int length1 = new SomeClass() .getStringCollection().iterator().next().length();
final int length2 = new SomeTypedClass<String>().getStringCollection().iterator().next().length(); // no more compilation error
}
}
我使用的是String
,但您可以使用Object
,因为T
实际上并未使用{/ p>}。
根据您的真实场景,可能值得考虑使用SomeTypedClass
课程做更多类似的事情:
class SomeTypedClass<T> {
public Collection<T> getTypedCollection(T object) {
return Collections.singleton(object);
}
}
然后你可以这样做:
final int length2 = new SomeTypedClass<String>().getTypedCollection("hello").iterator().next().length();
如果您只对源自String
的课程感兴趣,您也可以这样做:
class SomeTypedClass<T extends String> {
public Collection<T> getStringCollection(T object) {
return Collections.singleton(object);
}
}
然后你可以这样做:
final int length2 = new SomeTypedClass<String>().getStringCollection("hello").iterator().next().length();