疑問
equals()をオーバーライドした時に、
なぜ、引数のprivateフィールドを読めるのか?
Food.java
public class Food {
// ===privateなのに===
private final Double TAX = 1.08;
private String name;
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Food)) return false;
Food food = (Food) o;
// ===引数oのprivateフィールドに直接アクセス出来るの??===
return name != null ? name.equals(food.name) : food.name == null;
}
}
この疑問を実験してみました!!!!
実験1:privateフィールドって本当にアクセスできないの?
他のクラスでアクセスしてみましたが、
こちらはコンパイルエラーなので、
しっかりアクセスできませんでした。
CompileError
public class OtherClass {
public static void main(String[] args) {
Food tomato = new Food("トマト", 7, 100);
tomato.printInfo();
tomato.name = "違う名前";
System.out.println(tomato.name); //コンパイルエラー
}
}
実験2:もしかしてequals()だけなのか?
同じクラスにmain()を作成し、実行してみた。
こちら実行できたので、
どうやらequals()だけではないようです。
Food.java
public class Food {
private String name;
public Food(String name) {
this.name = name;
}
public static void main(String[] args) {
Food tomato = new Food("トマト", 7, 100);
tomato.name = "違う名前";
System.out.println(tomato.name); //違う名前
}
}
実験3:main()も特殊なメソッドだろうが(# ゚Д゚)
普通のメソッドでも
同様にアクセスできました
Food.java
public class Food {
private String name;
public Food(String name) {
this.name = name;
}
public void changeName(Food otherFood, String name) {
otherFood.name = name;
}
public String getName() {
return name;
}
}
OtherClass.java
public class OtherClass {
public static void main(String[] args) {
Food food = new Food("tomato");
food.changeName(food, "違う名前");
System.out.println(food.getName()); // 違う名前
}
}
結論
他のインスタンスでも、同じクラス内ならprivate fieldでも読めるし、書き変えも可能みたいです。
これはそのクラスが持つmainでも普通のメソッドでも同じようです。
ただし、危険な臭いがするので、
equals()以外で他のインスタンスのprivateフィールドにアクセスするのは
やめた方が良さそうです。