为什么我的代码只是工作,如果obj==null



我正在阅读关于private的内容,我发现了这个代码…我不明白为什么当我把obj == 0obj == 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);
        }
    }
}

这只用于测试目的,不应该在生产代码中使用。

相关内容

最新更新