public class Test { main(String args []) { People people1 = ); System.out.println(people1.name); // 直接通过People的实例对象访问name私有变量 } }
编译器会友好地提示:The field People.name is not visible,并在运行时候报error,这告诉我们不能不能通过people1.name直接访问私有实例变量name
但我们的访问器方法getName是定义为public的呀,所以我们能通过getName方法访问
public class Test { main(String args []) { People people1 = ); System.out.println(people1.getName()); } }
运行后输出:
彭湖湾
私有的变量对于类实例来说本是“不可见”的,但公有的访问器方法却有权让它暴露出来。
类内访问
在类定义的代码里,我们可以自由地访问私有实例变量,不过有一点要注意: 私有实例变量的最高访问权限是类,而不仅仅是单个对象(也就是说同一个类定义的不同的对象能够对各自的私有实例变量“互访”)
例如,在下我们通过 equalName方法判断People类的两个实例对象的name变量值是否相等
public class People { private String name; public People (String aName) { name = aName; } public boolean equalName (People other) { String otherName = other.name; // 访问另一个对象的私有的name变量 return name.equals(otherName); } }
在Test.java中:
public class Test { main(String args []) { People people1 = ); People people2 = ); People people3 = ); System.out.println(people1.equalName(people2)); System.out.println(people1.equalName(people3)); } }
输出结果:
// 说明people1和people3的name值相等
在equalName方法中,我们在方法参数中声明了同一个people类的另外一个实例对象other,并通过other.name直接取得它的私有实例变量并在方法中使用。运行是成功的,这意为着私有实例变量并不是为单个对象“所私有”,而是为整个类所“私有”。 这个类下的所有对象,都拥有对同一类下某个对象的私有实例变量的直接的访问权限
当然,不同类的对象, 就没有这种直接的访问权限了
实例变量和局部变量“交锋”
在方法中, 可以直接通过名称访问实例变量(隐式访问),也可以通过this去显式访问
事实上,以下两种方式效果是相同的
public class People { private String name; public People (String aName) { name = aName; // 隐式访问实例变量 } }
public class People { private String name; public People (String aName) { this.name = aName; // 显式访问实例变量 } }
当局部变量和实例变量同名的时候,局部变量会覆盖同名的实例变量,让我们看一个例子:
public class People { ; public People (String name) { System.+ name); //在构造函数中这样做有些怪异,但为了展示请不要介意 } }
在People类中,有一个实例变量name, 同时在构造函数中将通过参数的形式引入一个同名的局部变量
name,这个时候,我们通过name访问到的是局部变量name,而不是隐式访问的实例变量name:
请看Test.java中的测试:
public class Test { main(String args []) { People people1 = ); } }
运行后打印
输出:局部name变量
打印的是“局部name变量”而不是"实例name变量", 这代表, 同名的局部变量覆盖了对应的实例变量
嗯嗯,正因如此就会产生一些问题了:我们可能常常希望能够在构造函数中通过参数引入的局部变量的值初始化实例变量,但因为同名覆盖的问题却会带来一些烦恼: