概述
对自己之前对private修饰的严重理解错误进行记录,并展现一个极易被忽视的特性。
特性
1.被private修饰的变量和方法的访问权仅限于类的内部,即便获取该类的引用也无法访问。
2.一个类的方法可以访问这个类所有对象(包括其他对象)的私有数据(重点)。
代码
1.典型的错误示范,Two中的方法无法访问other的私有字段str,one也无法直接访问自己的str。
class One{
private String str;
One(String str){
this.str = str;
}
}
class Two{
private String str;
Two(String str){
this.str = str;
}
public boolean equals(One other){
return this.str.equals(other.str); //Error
}
}
public class Main {
public static void main(String[] args) {
One one = new One("123");
System.out.println(one.str); //Error
}
}
2.在该示例中,Employee的方法equals()的实现在Employee内部,因此可以正常访问到Employee对象的name;但此处同时可以访问other的私有对象name,此时我们并不在other的内部,却可以直接通过other这个引用去访问其私有变量name,这本来应该不可行,但正是由于前面所述的特性,才让此处区别于上一个示例使得可以访问。
class Employee{
private String name;
Employee(String name){
this.name = name;
}
public boolean equals(Employee other){
return this.name.equals(other.name);
}
}
public class Main {
public static void main(String[] args) {
Employee employee = new Employee("Jack");
Employee employee1 = new Employee("Jack");
//System.out.println(employee.name); //Error
if (employee.equals(employee1)){
System.out.println("The name is the same");
}
}
}
3.使用非私有的get()方法去改进1号错误程序。
class One{
private String str;
One(String str){
this.str = str;
}
public String getStr() {
return str;
}
}
class Two{
private String str;
Two(String str){
this.str = str;
}
public boolean equals(One other){
return this.str.equals(other.getStr()); //使用get方法访问
}
}
public class Main {
public static void main(String[] args) {
One one = new One("123");
Two two = new Two("123");
System.out.println(two.equals(one));
}
}
true
经验总结
1.一定要记住private修饰的变量和方法仅限于类的内部使用,而不是仅它自己可以使用,否则会误认为只要得到了一个对象的引用就可以直接访问自己的私有字段。
2.如果想要给出一个访问自己私有变量方法,可以设定并使用get、set方法。
3.同一个类的方法可以自由的直接访问自己这个类的私有成员,在实际中可以简化编程,例如在重写一个类的compareTo()方法时,可以不必使用get()方法获取。
4.这里我们会自然的想到工厂设计模式:通过一个工厂类中的静态方法或者静态成员来创建对象。例如LocalDate类,我们创建该类对象的时候就不是使用new和其构造方法,因为其构造方法是私有的,我们应该用该类提供的公有静态方法进入类的内部,再进行对象的实例化。除此之外还有诸如单例设计模式也都应用了这种方法创建和初始化类。