为什么以下代码无法编译?
class aa1 <String> {
public void fun(){
String s = ""; // not compiling
}
}
class aa2 <String> {
String s = ""; // not compiling
}
class aa3 <String> {
String s = (String)""; // compiling
}
可以告诉或给我链接 感谢。
答案 0 :(得分:6)
我认为你可能误解了仿制药背后的想法。关键是你的班级(在这种情况下为aa
)可以......嗯,通用。它不是一种固定类型,而是通过多态可以是任意数量的类型。泛型类型与变量名类似,但它表示一个类,而不是类的实例。你可以这样做:
class aa <T> {
public void fun(T myObject){
T s = myObject;
}
}
这是对泛型的适当使用。 T
只代表“某类”。 您发布的示例未编译的原因是因为您覆盖了String 的可见性(使其成为泛型类型,而不是java.lang.String
)。如果您不希望它是任何类,而是某些类的子集,您可以执行以下操作:
class aa <T extends MyInterface> {
public void fun(T myObject){
T s = myObject;
}
}
在这种情况下,您可以保证类T
的实例也扩展了接口MyInterface
。但是,您无法扩展String
,因为它是最终的。如果您只想设置String
对象,则根本不需要泛型:
class aa {
public void fun(){
String s = "";
}
}
有关泛型的更多信息,请阅读the Java tutorials on generics。
答案 1 :(得分:2)
在这种情况下,泛型参数“String”会隐藏java.lang.String。
在类中,如果你声明了字符串s并将其数据类型指定为“java.lang.String”,那么编译器就不会抱怨。public class aa<String> {
java.lang.String s = "" ;
}
答案 2 :(得分:1)
你的代码毫无意义 - 声明毫无意义 - 你真的想在这做什么?
您遇到问题的原因是您正在制作一个隐藏JDK的java.lang.String的泛型声明。
你也是3次宣布同一个班级。像这样的东西会编译,但仍然可能达不到你想要的效果。
class aa<NotString> {
public void fun() {
String s = ""; // compiles
}
}
class aa2<NotString> {
String s = ""; // compiles
}
class aa3<NotString> {
String s = (String) ""; // compiling
}
答案 3 :(得分:0)
好吧,您的通用参数名称(String
)似乎隐藏了java.lang.String
类型。
我建议您重命名通用参数。顺便问一下,您希望s
为哪种类型:java.lang.String
或与参数相同?在后一种情况下,编译器如何将""
(类型为java.lang.String
)分配给泛型参数表示的潜在无关类型?
答案 4 :(得分:0)
在您的示例中,您将String
声明为标识符。您不得使用关键字或类型名称。 (Generics Tutorial)。
答案 5 :(得分:0)
由于您声明了泛型String
,它将覆盖默认的java.lang.String
类型,因此您的代码就像输入:
class aa<T> {
T s = "";
}
类型擦除后, T
只是Object
,但由于它可以用任何东西初始化(例如Integer
),编译器不会让你分配String
对它。