Java 私有字段可见性

Posted

技术标签:

【中文标题】Java 私有字段可见性【英文标题】:Java Private Field Visibility 【发布时间】:2010-09-23 15:41:05 【问题描述】:

所以前几天我正在创建一个类并使用 Eclipse 的方法创建 equals 方法时,我意识到它生成了以下工作代码:

class Test 
  private int privateInt;
  [...]
  public boolean equals(Object obj) 
    [...]
    Test t = (Test) obj;
    if ( t.privateInt == privateInt ) 
    [...]
  

t.privateInt..????应该是私人的!所以我想除了私有、受保护、包保护和公共之外,还有一种字段可见性。

那么这里发生了什么?这个怎么称呼? 有人会在哪里使用它? 这不会破坏封装吗?如果该类没有 mutator 而我更改了它怎么办? C++ 也会发生这种情况吗?这是一个面向对象的习语吗?如果不是,那为什么 Java 会这样做呢?

一般来说,我在哪里可以找到有关这方面的信息?

谢谢。

【问题讨论】:

【参考方案1】:

它可以从同一类的不同实例访问。

据this page(加粗我的):

在成员级别,您也可以像***类一样使用公共修饰符或无修饰符(包私有),并且具有相同的含义。对于成员,还有两个额外的访问修饰符:private 和 protected。 private 修饰符指定该成员只能在其自己的类中访问。

为了清楚起见,我将重写这一行:

if ( t.privateInt == this.privateInt )

我们可以同意应该允许“this.privateInt”:您正在从消息“equals”已发送到的 Test 类的实例中访问它。

“t.privateInt”应该是可见的不太清楚,因为 t 是 Test 类的一个单独实例,我们不在其 equals 方法中执行。但是 java 允许这样做,因为两个对象(t 和 this)都属于同一类 Test 并且可以看到彼此的私有成员。

【讨论】:

好的...我现在明白了...但是为什么呢?为什么 Java 会让这种情况发生?你能想到一些现实生活中的例子吗?我明白为什么它应该在 equals.. 但必须有一个更好的例子.. 唯一的其他示例类似于equals,其中您将获得类的另一个实例作为参数。至于为什么 Java 这样做,它在 OO 语言中是相当标准的——C++ 的工作方式相同。在 C++ 中重载 ==:artis.imag.fr/~Xavier.Decoret/resources/C++/operator==.html Soooo... 这是非常没用的琐事? 作为另一个无用的琐事,private 自从它第一次出现在 Simula-67 中就一直以这种方式工作(在那里它被称为 hidden,但它也是 3 个经典私有/ protected/public 级别,它的工作方式与在 C++、Java、C# 等中的工作方式完全相同。【参考方案2】:

迈克说得很对;您将对象(类的实例)与类本身混淆了。成员是 class 的私有成员,而不是类的任何特定 instance

我记得当我刚接触 Java 时对此感到惊讶。

【讨论】:

或者他把 this.field 和 obj_of_same_class.field 混淆了 您能否详细说明一下或提供一个链接以帮助我了解更多。【参考方案3】:

您在同一个类中引用它。因此,您知道自己在做什么,不需要保护自己。

【讨论】:

【参考方案4】:

允许访问其他实例的私有成员的一个重要原因是允许“复制”功能——否则它们几乎是不可能的。另外,如果您不允许其他实例访问,您将允许哪些静态方法?

【讨论】:

【参考方案5】:

可以访问同一类的另一个实例的私有变量。这是因为您正在直接处理类的实现,这无论如何都需要您了解其内部的“私有”变量。

【讨论】:

【参考方案6】:

对这种混淆的简单回答是记住私有字段仅在它们被初始化(和定义)的类中是可见的......所以当你在类中创建一个类的对象时,你可以始终通过对象引用访问该类的私有字段。可能你觉得它很难,但是当你在定义它的类中使用它时,认为私有字段就像一个公共字段。

【讨论】:

以上是关于Java 私有字段可见性的主要内容,如果未能解决你的问题,请参考以下文章

Java 私有构造函数可见性

Java内存模型与共享变量可见性

Java内存模型与共享变量可见性

在java中,如果没有给变量指定是公有或是私有,默认是啥?

java 可见性简单总结

PHP 朋友/包可见性