简体   繁体   English

调用使用泛型定义的方法时出现“错误:找不到符号”

[英]“error: cannot find symbol ” when calling a Method defined using Generics

After reading through the Generics info I am attempting a simple sample and encountering the following error. 阅读完泛型信息后,我尝试一个简单的示例,并遇到以下错误。

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

Without the reference to "temp.x" it compiles which leads me to believe the definition is correct but possibly the way the variable is referenced is the issue. 没有引用“ temp.x”,它会编译,这使我相信定义是正确的,但可能是引用变量的方式出了问题。 Or it could be the actual implementation is wrong. 或可能是实际实施有误。 Not sure. 不确定。

The main class has a method which can be called by either of the 2 inner classes. 主类具有可以由2个内部类之一调用的方法。 When called, the method attempts to access the variable specific to the inner class that called it. 调用时,该方法尝试访问特定于调用它的内部类的变量。

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)
^^^^^^^^^^^^^^^^

Without further specification, eg <T extends InnerClass1> , the only thing that is known about T within that method is that it extends Object , and for Object , the attribute x is not defined. 没有进一步的说明,例如<T extends InnerClass1> ,该方法中关于T的唯一已知信息是它扩展了Object ,并且对于Object ,未定义属性x

Maybe you should define a common super-class for those two classes, and declare x in that super-class. 也许您应该为这两个类定义一个公共的超类,并在该超类中声明x

In order to get the value x from each class dynamically, you can define a common interface or abstract class for InnerClass1 and InnerClass2 to implement or extend . 为了动态地从每个类获取值x ,可以为InnerClass1InnerClass2定义一个公共interfaceabstract classimplementextend This allows the inheritance of methods and variables. 这允许方法和变量的继承。 Seeing that both holds a value of type T , let us create an interface called ValueHolder<T> : 看到两者都持有T类型的值,让我们创建一个名为ValueHolder<T>interface

interface ValueHolder<T> {
    public T getValue();
}

Both the InnerClass1 and InnerClass2 will need to implement this interface: InnerClass1InnerClass2都需要实现此接口:

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;
    }
}

As you can see, InnerClass1 implements ValueHolder<Integer> , meaning the inherited getValue methods return type will be Integer . 如您所见, InnerClass1实现了InnerClass1 ValueHolder<Integer> ,这意味着继承的getValue方法的返回类型将是Integer The same goes for InnerClass2 , which implements ValueHolder<String> . 实现了InnerClass2 ValueHolder<String> InnerClass2也是如此。

Change your tryThis as follows: 更改您的tryThis ,如下所示:

private <T> void tryThis(ValueHolder<T> temp) {
    System.out.println("Value = " + temp.getValue());
}

Now each value can be printed like this: 现在可以像这样打印每个值:

Generics g = new Generics();
g.tryThis(new InnerClass1());
g.tryThis(new InnerClass2());

Output: 输出:

X = 100
X = 200

T in in

private <T> void tryThis(T temp)</code>

is just a placeholder for any class. 只是任何课程的占位符。 The compiler knows nothing more about it, so it knows nothing about the symbol x as well. 编译器对此一无所知,因此对符号x也一无所知。

To accomplish what you are trying to do, you would need something like this: 要完成您想做的事情,您将需要以下内容:

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

}

However, you would not need Generics for this specific case: 但是,对于这种特定情况,您将不需要泛型:

    private void tryThis2(MyClass temp) {
        System.out.println("X = " + temp.x);
    }

would accomplish the same. 将达到相同的效果。

Generics are very complex, although they look easy to use. 尽管泛型看起来易于使用,但它们非常复杂。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM