对于类型T,Java泛型,方法base()未定义

use*_*754 1 java generics types undefined

我试图理解java中的泛型,并尝试这个简单的例子,但不能使它工作; 它回来时有错误

线程"main"中的异常java.lang.Error:未解决的编译问题:javaTest.Main.main(Main.java)javaTest.Main.testShape(Main.java:21)中的类型T未定义方法base() :25)

下面是代码

class Shape{
    int id=1;
    void base(){
        System.out.println("Shape.base()");
    }
}

// unrelated class, but same func name
class OtherShape{
    float id=1.1f;
    void base(){
        System.out.println("OtherShape.base()");
    }
}

public class Main {

    static <T>void testShape(T shape){
        shape.base();
    }

    public static void main(String[] args) {        
        testShape(new Shape() );
        testShape(new OtherShape());        
    }
}
Run Code Online (Sandbox Code Playgroud)

关于如何让它发挥作用的任何想法?

Zby*_*000 8

在Java中,泛型是在没有外部上下文的情况下编译的,因此代码必须是有效的,而不知道最后它将如何被调用.

声明某些东西<T>意味着你可以传递任何对象,所以T var意味着在编译时var应该只是java.lang.Object.因此var.base()没有意义,因为java.lang.Object没有提供所谓的方法base().

你可以告诉它T至少Shape是例如通过声明<T extends Shape>,然后你可以传递任何继承自的东西Shape.但是,您的第二个示例仍然无法OtherShape继承Shape,即它不满足条件<T extends Shape>.

要完全修复它,它应该如下所示:

class Shape{
    int id=1;
    void base(){
        System.out.println("Shape.base()");
    }
}

// unrelated class, but same func name
class OtherShape extends Shape{
    float id=1.1f;
    @Override
    void base(){
        System.out.println("OtherShape.base()");
    }
}

public class Main {

    static <T extends Shape> void testShape(T shape){
        shape.base();
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

向前一步是使Shape一个接口,而创建的每一个形状类(TriangleShape,OtherShape,...)实现该接口.

请注意,在您的示例中,您并不真正需要泛型,如果您稍后需要引用相同的类型,它们非常有用,例如从方法返回它:

    static <T extends Shape> T testShape(T shape){
        shape.base();
        return shape;
    }
Run Code Online (Sandbox Code Playgroud)

在上面的示例中,您仍然可以将此方法的结果分配给您在参数中传递的相同类型,因为参数类型和返回类型相同(T).