public class UnderstandingMemoryManagement1 {
private static boolean flag = false;
public static void main(String[] args) {
Set<String> mainNameSet = getNameSet();
mainNameSet.add("Name-6");
Log.logInfo(getNameSet() == mainNameSet);
Log.logInfo(getNameSet().equals(mainNameSet));
Log.logInfo("------main() END------");
}
public static Set<String> getNameSet() {
Set<String> nameSet = new TreeSet<>();
nameSet.add("Name-1");
nameSet.add("Name-2");
nameSet.add("Name-3");
nameSet.add("Name-4");
Set<String> otherSet = nameSet;
otherSet.add("Name-5");
if (!flag ) {
flag = true;
Log.logInfo(nameSet == otherSet);
Log.logInfo(nameSet.equals(otherSet));
Log.logInfo("------getNameSet() END------");
}
return nameSet;
}
}
当我运行上面的代码时,为什么输出如下:-
INFO: true
INFO: true
INFO: ------getNameSet() END------
INFO: false
INFO: false
INFO: ------main() END------
为什么第二次返回false为何不为真? 据我所知,java复制了引用而不是对象。当它处理引用而不是对象时,对于第二种情况也应返回true。请给我解释一下。
答案 0 :(得分:2)
方法getNameSet()
每次被调用时都会返回对新TreeSet
对象的引用。您在main()
中调用此方法 3 次,因此得到三种不同的 TreeSet
对象。
第一个false
来自两个不同的TreeSet
对象与==
运算符的比较。这些是不同的对象,具有不同的参考值。
第二个false
来自mainNameSet.add("Name-6");
,它修改了第一个TreeSet
,因此不再相等。
答案 1 :(得分:2)
您首先调用getNameSet()
方法并将其结果存储到mainNameSet
变量中。该方法包含一条语句,其中构造了一个新的TreeSet
实例,然后您将返回此新实例:
Set<String> nameSet = new TreeSet<>();
...
return nameSet;
然后您要执行以下操作:
getNameSet() == mainNameSet
您再次 调用getNameSet()
,这反过来构造了一个新的TreeSet
实例并返回它。 对于每个getNameSet()
呼叫,您都有不同的TreeSet
实例。
这就是为什么比较返回false
的原因。
Java is always pass-by-value,如果是引用,则意味着复制了传递给方法的引用。
void handle(Dog inputDog) {
inputDog = new Dog("Jack");
}
Dog myDog = new Dog("Fluffy");
handle(myDog);
// The name of the dog referenced by 'myDog' is still Fluffy.
// Upon calling the 'handle' method, a reference to my dog named Fluffy is
// copied to the local reference 'inputDog'. A new dog with the name Jack is
// constructed and stored into the 'inputDog' variable, which is distinct
// from the 'myDog' variable. So 'myDog' doesn't change at all.