簡體   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