java陷阱常见面试题_Java常见陷阱

java陷阱常见面试题

总览

Java是一种极简主义的语言,具有比其他语言故意更少的功能,尽管如此,Java仍然具有产生奇怪效果的边缘情况,甚至具有令人惊讶的效果的一些常见情况也会使您轻而易举。 如果您习惯于阅读另一种语言,则可以轻松地以错误的方式阅读Java,而不会感到困惑。

变量仅是引用或原语

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

String s = "Hello";

这回答了许多混乱的领域,例如;

  • 问:如果String是不可变的,该如何更改。 例如 s + =“!”;
  • 答:您不能使用普通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

对于Integer,对象池从-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(),甚至可以通过

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

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

如前所述,hashCode不是存储位置,即使它以十六进制打印也是如此。 而且,类名,特别是对于数组,令人困惑。 例如; String []打印为[Ljava.lang.String; [表示它是一个数组,L表示它是一个“语言”创建的类,而不是像BTW这样具有代码B的字节之类的基元。 表示课程结束。 例如说你有一个像

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

打印类似

[Ljava.lang.String;@45ee12a7

不幸的是,您必须知道该类是一个对象数组,例如,如果您只有对象字,那么您将遇到问题,并且必须知道调用Arrays.toString(words)。 这种中断封装的方式非常糟糕,并且在StackOverflow上经常造成混乱。

我曾问过Oracle公司的其他开发人员这件事,我的印象是现在很难修复它。

参考: Vanilla Java博客上来自我们JCG合作伙伴 Peter Lawrey的Java常见陷阱

翻译自: https://www.javacodegeeks.com/2014/03/common-gotchas-in-java.html

java陷阱常见面试题

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值