繁体   English   中英

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

[英]“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 ,可以为InnerClass1InnerClass2定义一个公共interfaceabstract classimplementextend 这允许方法和变量的继承。 看到两者都持有T类型的值,让我们创建一个名为ValueHolder<T>interface

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

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

如您所见, 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.

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