Java – private access with self-contained generics

Combining private field access with CRTP in Java seems to find a strange edge in visibility rules:

public abstract class Test<O extends Test<O>> implements Cloneable {
    private int x = 0;

    @SuppressWarnings("unchecked")
    @Override
    protected final O clone() {
        try {
            return (O) super.clone();
        } catch (CloneNotSupportedException ex) {
            throw new AssertionError(ex);
        }
    }

    public final int getX() {
        return x;
    }

    public final O withX(int x) {
        O created = clone();
        created.x = x;  // Compiler error: The field Test<O>.x is not visible
        return created;
    }
}

Just change the withx () method to this

public final O withX(int x) {
        O created = clone();
        Test<O> temp = created;
        temp.x = x;
        return created;
    }

... make the code compile I tested this in Oracle's javac and eclipse compilers What gives?

Solution

This is not really a generic problem JLS inheritance rules make private fields invisible in subclasses Because x is private, it is not a member of type O, even if it is a member of type test < o > O is a subtype of test < o > If you have used the following code:

public final O withX(int x) {
    Test<O> created = clone();
    created.x = x;
    return (O) created;
}

It will work This is an instance of LSP that Java does not support, but it is only a local problem of the type system, because private fields can only be used for objects of the same type If it doesn't work, the private field won't be private I don't think it's a good idea to have a special exception to the rules of recursive templates

Please note that this is not really a limitation on what you can do You can convert subtypes to supertypes at any time to make changes, just as in alternative code

The content of this article comes from the network collection of netizens. It is used as a learning reference. The copyright belongs to the original author.
THE END
分享
二维码
< <上一篇
下一篇>>