问题描述
阅读完泛型信息后,我尝试一个简单的示例,并遇到以下错误。
MyClass.java:32: error: cannot find symbol
System.out.println("X = " + temp.x);
^
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
1 error
没有引用“ temp.x”,它会编译,这使我相信定义是正确的,但可能是引用变量的方式出了问题。 或可能是实际实施有误。 不确定。
主类具有可以由2个内部类之一调用的方法。 调用时,该方法尝试访问特定于调用它的内部类的变量。
public class MyClass {
public class InnerClass1 {
int x = 100;
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 {
int x = 200;
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
MyClass x = new MyClass();
}
private <T> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
1楼
symbol: variable x
location: variable temp of type T
where T is a type-variable:
T extends Object declared in method tryThis(T)
^^^^^^^^^^^^^^^^
没有进一步的说明,例如<T extends InnerClass1> ,该方法中关于T的唯一已知信息是它扩展了Object ,并且对于Object ,未定义属性x 。
也许您应该为这两个类定义一个公共的超类,并在该超类中声明x 。
2楼
为了动态地从每个类获取值x ,可以为InnerClass1和InnerClass2定义一个公共interface或abstract class以implement或extend 。
这允许方法和变量的继承。
看到两者都持有T类型的值,让我们创建一个名为ValueHolder<T>的interface :
interface ValueHolder<T> {
public T getValue();
}
InnerClass1和InnerClass2都需要实现此接口:
public class InnerClass1 implements ValueHolder<Integer> {
private int x = 100;
@Override
public Integer getValue() {
return this.x;
}
}
public class InnerClass2 implements ValueHolder<String> {
public String x = "200";
@Override
public String getValue() {
return this.x;
}
}
如您所见, InnerClass1实现了InnerClass1 ValueHolder<Integer> ,这意味着继承的getValue方法的返回类型将是Integer 。
实现了InnerClass2 ValueHolder<String> InnerClass2也是如此。
更改您的tryThis ,如下所示:
private <T> void tryThis(ValueHolder<T> temp) {
System.out.println("Value = " + temp.getValue());
}
现在可以像这样打印每个值:
Generics g = new Generics();
g.tryThis(new InnerClass1());
g.tryThis(new InnerClass2());
输出:
X = 100
X = 200
3楼
in
private <T> void tryThis(T temp)</code>
只是任何课程的占位符。 编译器对此一无所知,因此对符号x也一无所知。
要完成您想做的事情,您将需要以下内容:
public class Generics {
abstract class MyClass {
int x;
}
public class InnerClass1 extends MyClass {
InnerClass1() {
super.x = 100;
}
public void runThis() {
tryThis(this);
return;
}
}
public class InnerClass2 extends MyClass {
InnerClass2() {
super.x = 200;
}
public void runThis() {
tryThis(this);
return;
}
}
public static void main(String[] args) {
Generics x = new Generics();
x.new InnerClass1().runThis();
x.new InnerClass2().runThis();
}
private <T extends MyClass> void tryThis(T temp) {
System.out.println("X = " + temp.x);
}
}
但是,对于这种特定情况,您将不需要泛型:
private void tryThis2(MyClass temp) {
System.out.println("X = " + temp.x);
}
将达到相同的效果。
尽管泛型看起来易于使用,但它们非常复杂。