Java 中的常见问题

Java 是一种极简主义的语言,它故意比其他语言少一些功能,但它的边缘情况会产生奇怪的效果,甚至一些常见的情况会产生令人惊讶的效果,从而使粗心大意的人绊倒。如果您习惯于阅读另一种语言,则很容易以错误的方式阅读 Java,从而造成混乱

变量只是引用或原语

没错,变量不是对象。这意味着当您看到以下内容时, s 不是 object,它不是 String,它是  对 String的引用
 String s = "Hello";

这回答了许多令人困惑的领域,例如;

问:如果 String 是不可变的,我该如何更改它。例如。s += "!";

A:你不能在普通的Java中,你只能改变一个对String的引用。

== 比较引用,而不是它们的内容。

更令人困惑的是,有时使用 == 是可行的。如果您有两个相同的不可变值,JVM 也可以尝试使引用相同。例如

String s1 = "Hi", s2 = "Hi";
   Integer a = 12, b = 12;

在这两种情况下,都使用了对象池,因此引用最终是相同的。s1 == s2 和 a == b 都是真的,因为 JVM 已经对同一个对象进行了引用。但是,稍微改变一下代码,这样 JVM 就不会汇集对象,并且 == 返回 false,这可能是出乎意料的。在这种情况下,您需要使用 equals。

String s3 = new String(s1);
   Integer c = -222, d = -222;
    s1 == s2      // is true
    s1 == s3      // is false
    s1.equals(s3) // is true
    a == b        // is true
    c == d        // is false (different objects were created)
    c.equals(d)   // is true

对于整数,对象池从 -128 开始到至少 127(可能更高)

Java 按值传递引用

所有变量都按值传递,甚至引用。这意味着当您有一个引用对象的变量时,会复制此引用,但不会复制对象。例如

public static void addAWord(StringBuilder sb) {
     sb.append(" word");
     sb = null;
}
StringBuilder sb = new StringBuilder("first ");
addWord(sb);
addWord(sb);
System.out.println(sb); // prints "first word word"

用的对象可以更改,但对复制的引用的更改对调用者没有影响。

在大多数 JVM 中,Object.hashCode() 与内存位置没有任何关系

hashCode() 必须保持不变。如果没有这个事实,HashSet 或 ConcurrentHashMap 之类的哈希集合将无法工作。但是,该对象可以位于内存中的任何位置,并且可以在您的程序不知道发生这种情况的情况下更改位置。使用 hashCode 的位置是行不通的(除非你有一个不移动对象的 JVM)

对于 OpenJDK 和 HotSpot JVM,hashCode() 按需生成并存储在对象的标头中。使用 Unsafe 您可以查看 hashCode() 是否已设置,甚至可以通过 over 更改它

Object.toString() 做了一些令人惊讶而不是有用的事情

toString() 的默认行为是打印类的内部名称和 hashCode()。

如前所述,hashCode 不是内存位置,即使它以十六进制打印。类名,尤其是数组的类名也令人困惑。例如; String[] 打印为 [Ljava.lang.String; [ 表示它是一个数组, L 表示它是一个“语言”创建的类,而不是像字节一样的原始类型,顺便说一句,它的代码是 B。 ; 表示类的结束。例如说你有一个像

String[] words = { "Hello", "World" };
System.out.println(words);

打印类似的东西

[Ljava.lang.String;@45ee12a7

不幸的是,您必须知道该类是一个对象数组,例如,如果您有 justObject 单词,那么您就有问题,您必须知道调用 Arrays.toString(words)。这种破坏封装的方式相当糟糕,也是 StackOverflow 上常见的混淆

 最后,有兴趣想要学习相关资料的朋友点赞三连+关注后私信后回复《555》即可免费获取

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值