我正在阅读关于private的内容,我发现了这个代码…我不明白为什么当我把obj == 0
或obj == 1
我得到错误和代码不工作,但它只是工作时obj == null
。你能给我描述一下代码是如何工作的,为什么它只在obj == null
时工作?
package person;
public class Cat {
private static Cat obj = null;
public Cat object () {
if(obj == null){
obj = new Cat();
}
return obj;
}
public void display() {
System.out.print("obj is null");
}
public static void main(String[] args) {
Cat myobj = new Cat();
myobj.display();
}
}
输出为
obj is null
谢谢
不能将cat引用指向int原语,这没有意义。
它与null一起工作,因为所有引用都可以设置为null。
当它为null时,它会工作,因为对象是在构造函数中正确创建的:
if(obj==null){
obj=new Cat();
}
当您将obj设置为1或0时,您会得到一个错误,因为JVM不知道如何将整数强制转换为Cat类。如果需要将对象j声明为整型,则可以将其声明为int而不是Cat。
在Java中不能比较基本类型和对象。一般来说,Java是类型安全的,正如这篇维基百科文章
所描述的那样。另一方面,c++支持更隐式的类型转换(并且与Java有不同的类型系统),其中像obj == 0这样的检查是检查对象上是否有空指针的一种可能方法。我可以修复代码使
obj == 0;
工作吗?
不,你不能。但是你可以让addressOf(obj) == 0;
工作与一个丑陋的hack:
package person;
import sun.misc.Unsafe;
import util.Dirty;
public class Cat {
private static Cat obj = null;
public Cat object () {
if(addressOf(obj) == 0){
obj = new Cat();
}
return obj;
}
public void display() {
System.out.print("obj is null");
}
public static void main(String[] args) {
Cat myobj = new Cat();
myobj.display();
}
static final Unsafe UNSAFE = /* ... */;
static final int REF_SIZE = /* ... */;
static final int OBJECT_ARRAY_BASE = UNSAFE.arrayBaseOffset(Object[].class);
public static long addressOf(Object o) {
return addressOf(o, REF_SIZE);
}
public static long addressOf(Object o, int oopSize) {
Object[] array = new Object[]{o};
switch (oopSize) {
case 4:
return UNSAFE.getInt(array, OBJECT_ARRAY_BASE) & 0xFFFFFFFFL;
case 8:
return UNSAFE.getLong(array, OBJECT_ARRAY_BASE);
default:
throw new Error("unsupported address size: " + oopSize);
}
}
}
这只用于测试目的,不应该在生产代码中使用。