子类中的私有字段可以在父类中访问。

3

这段内容在JLS(第8.3节)中有所描述:

“超类的私有字段可能对子类可见 - 例如,如果两个类都是同一类的成员。然而,私有字段永远不会被子类继承。”

你能举一个例子来说明这个说法吗?

我知道我们可以写:

public class MyClass {
    private int x = 1;

    public void testExample(MyClass m) {
        m.x = 2;
    }
}

在这里我们访问了私有字段m.x,但是我们没有“超类” - “子类”。

(意思是说,在该段代码中,虽然访问了一个私有字段,但是并没有涉及到继承关系)


1
请参阅 https://groups.google.com/d/msg/java-lang-fans/KVmmgeSCHkA/7nAQolGcsjwJ,其中包含有关编程的内容。 - ZhongYu
2个回答

3

这是关于嵌套类的讨论 - 这是一个例子:

public class Test {
    public static void main(String[] args) {
        new Subclass(10).foo();
    }

    static class Superclass {
        private int x;

        Superclass(int x) {
            this.x = x;
        }
    }

    static class Subclass extends Superclass {
        Subclass(int x) {
            super(x);
        }

        public void foo() {
            Superclass y = this;
            System.out.println(y.x);
        }
    }
}

它是有效的,因为根据JLS 6.6

否则,成员或构造函数被声明为私有,只有在包含该成员或构造函数声明的顶级类(§7.6)的主体内,才允许访问

这里使用的xTest的主体内,它是包含x声明的顶级类......尽管如果您尝试使用未限定的x,或者只是this.x,那将失败...... 正是因为x实际上没有被继承(根据规范的那部分引用)。


不是编译错误 - 成员this.x不存在,因为 x 没有被继承。 - ZhongYu
@bayou.io:啊哈,很好的发现,也是问题中引用的正是一个很好的例子 :) - Jon Skeet
谢谢Jon,我认为你是对的。而且这个问题是更常见规则的一个特例:所有嵌套类都可以访问其他嵌套类的所有私有字段/方法。 - Vitaly
@Vitaly:在相同的封闭外部类中,是的。 - Jon Skeet

0

“visibility”方法-顾名思义,与程序员能够看到的方法和变量有关。一般情况下,类中声明的变量只要在类定义内,即使它们被声明为私有变量并由该类的实例化对象(而不是“this”)引用,也始终可见。

关于可见性和封装的规则,在设计上旨在确保程序员不会意外访问会破坏功能的变量和方法。例如,如果您手动调用java.util.Random的方式,可能会破坏其工作方式。

private static long seedUniquifier() {
    // L'Ecuyer, "Tables of Linear Congruential Generators of
    // Different Sizes and Good Lattice Structure", 1999
    for (;;) {
        long current = seedUniquifier.get();
        long next = current * 181783497276652981L;
        if (seedUniquifier.compareAndSet(current, next))
            return next;
    }
}

(摘自Sun JDK源代码)

然而,在您编写的代码范围内,通常认为可以调用定义为该类类型的对象上的私有变量/方法,因为假定作为问题代码的程序员和编写者,您具备管理代码所需的权威、代理和专业知识。

因此,通常情况下,无论变量是否声明为私有,以下代码都是可以的:

public class Test {
    private float internalValue;
    public boolean isBigger(Test t) {
        return internalValue > t.internalValue;
    }
}

将始终有效。


你的示例是从声明它的类中的代码访问私有字段。我不认为这就是OP所询问的内容。 - Jon Skeet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接