Java中常见的坑_JAVA_编程开发_程序员俱乐部

中国优秀的程序员网站程序员频道CXYCLUB技术地图
热搜:
更多>>
 
您所在的位置: 程序员俱乐部 > 编程开发 > JAVA > Java中常见的坑

Java中常见的坑

 2014/7/18 12:30:12  flycars001  程序员俱乐部  我要评论(0)
  • 摘要:变量要么是引用,要么是基础类型这是对的,变量不是对象。也就是说在下面这个例子里,s不是个对象,也不是字符串,它只是一个字符串的引用。Strings="Hello";这个能解释很多的问题,比如:问题:如果说字符串是不可变的,为什么我能修改它?s+=“!”回答:在Java里是不可变的,你改变的只是引用而已。==比较的是引用,不是内容让人更混乱的是,有时候用==是能比较内容的。如果你有两个一样的不可变值,JVM会尝试引用同一个对象。Strings1="Hi",s2="Hi";Integera=12
  • 标签:Java

 变量要么是引用 ,要么是基础类型

  这是对的,变量不是对象。也就是说在下面这个例子里,s不是个对象,也不是字符串,它只是一个字符串的引用。   String s = "Hello";   这个能解释很多的问题,比如: 问题:如果说字符 串是不可变的,为什么我能修改它? s+=“!” 回答:在Java里是不可变的,你改变的只是引用而已。   ==比较的是引用,不是内容   让人更混乱的是,有时候用==是能比较内容的。如果你有两个一样的不可变值,JVM会尝试引用 同一个对象 。   String s1 = "Hi", s2 = "Hi";   Integer a = 12, b = 12;    这两个例子中用到了对象池,所以最后引用 的是同样的对象。s1==s2和a==b都是返回true,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 API你看到hashCode是否已经生成了,甚至还可以修改它。  Object.toString那些不为人知的事情   toString的默认行为是打印类的的内部名 称还有对象的hashCode。 上面已经提到,hashCode并不是内存地址,尽管它是用16进制打印的。同样的,类名,尤其是数组的类名,更容易让人头晕。比如说String[]的 名称是[Ljava.lang.String; 这个[表明它是个数组,L说明它是Java语言(Language)创建的类,并不是基础类型比如byte这些,顺便提一下byte内部名称是B。;号标 识类的结束。比如你有个这样的数组:   String[] words = { “Hello”, “World” };   System.out.println(words);   输出会是这样:   [Ljava.lang.String;@45ee12a7   很不幸你只知道这是个对象数组。如果你只有一个Object实例words,这样是不够的,你得调用下Arrays.toString(words)。这极其恶劣地破坏了封装的原则,在StackOverflow上面这也是最常见的一类问题。   我问过Oracle的好些个工程师,从他们的反馈感觉,这个问题目前很难解决。
发表评论
用户名: 匿名