Java泛型类型,可以扩展,也可以是父类

Rob*_*Fry 1 java generics

我正在寻找一些如下所示的代码:

public class Parent<T is_or_extends Parent<T>> {
    public T function() {
        // do some stuff //
        return correct();
    }
    public T correct() {
        return (T) this;
    }
}
Run Code Online (Sandbox Code Playgroud)

这样任何子类都可以访问其他父函数,但仍然是独立的类(没有将function()的返回值向上转换为Parent的实例).程序员也可以独立使用Parent类(因此可以创建Parent的实例而不使用function()向下转换返回对象)

执行:

public class Child extends Parent<Child> {}
Run Code Online (Sandbox Code Playgroud)

用法:

Child child = new Child(); // ok
Parent<Child> polymorph = new Child(); // ok
Parent<Parent> parent = new Parent<Parent>(); // ERROR!
Run Code Online (Sandbox Code Playgroud)

为了概述差异,这不是方法链的问题.相反,当父类接受子类的泛型时,它不能再单独用作类(使用上面的代码),因为new Parent<Parent>()不会编译(当用" is_or_extends" 替换" "时extends)

我的目标:

我想要实现的是父类,当扩展时,function()将返回子类的对象而不是父类.

我会使用泛型类型来告诉父类哪个子类调用了该函数,但是我不能再使用父类的对象而不会遇到异常.一个例子如下:

public static class Parent<T extends Parent<T>> {}
public static class Child extends Parent<Child> {}

public static void main(String[] args) {
    // This will not compile as Parent cannot extend Parent
    Parent<Parent> parent = new Parent<Parent>();

    // This will work as Child extends Parent
    Child child = new Child();
}
Run Code Online (Sandbox Code Playgroud)

提前致谢.

shm*_*sel 7

extends 意味着"是或扩展".你的例子不编译的原因是因为inner Parent是一个原始类型,它不是一个有效的替代品T extends Parent<T>."正确"类型看起来像这样:Parent<Parent<Parent<...>>>ad infinitum.显然这种类型是不可能宣布的.

一种解决方案是像这样实例化它:

Parent<?> parent = new Parent<>();
Parent<?> derived = parent.function();
Run Code Online (Sandbox Code Playgroud)

这是有效的,因为编译器已经知道它T是某些子类Parent<?>.这个技巧的一个缺点是,如果无法推断类型,它将无法工作,例如使用匿名类时.

另一种可能的方法 - 取决于父/子关系的性质 - 是创建一个额外的类来扩展基础,只是为了它的类型解析:

// Parent functionality in here
public static abstract class Base<T extends Base<T>> {}

// This can be empty, or have just constructors if necessary
public static class Simple extends Base<Parent> {}

// Child functionality in here
public static class Extended extends Base<Extended> {}
Run Code Online (Sandbox Code Playgroud)