[英]“error: cannot find symbol ” when calling a Method defined using Generics
阅读完泛型信息后,我尝试一个简单的示例,并遇到以下错误。
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);
}
}
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
。
为了动态地从每个类获取值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
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);
}
将达到相同的效果。
尽管泛型看起来易于使用,但它们非常复杂。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.