Java中常见的坑
概述
Java是门极简风格的语言,比其它语言相比,它故意保持较少的特性,不仅在有些不常见的情况下会出些奇奇怪怪的错误,即使很一般的情况下也有可能让人栽根头。如果你习惯了别的语言,你读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的好些个工程师,从他们的反馈感觉,这个问题目前很难解决。
原创文章转载请注明出处:http://it.deepinmind.com/java/2014/03/07/Java-common-problems.html
Java中常见的坑的更多相关文章
- Java中常见的5种WEB服务器介绍
这篇文章主要介绍了Java中常见的5种WEB服务器介绍,它们分别是Tomcat.Resin.JBoss.WebSphere.WebLogic,需要的朋友可以参考下 Web服务器是运行及发布Web应用的 ...
- Java中常见的Exception种类
Java中常见的Exception种类 1.ClassNotFoundException 2.IOException 3.NoSuchFieldException 4.NoSuchMethodExce ...
- Java基础-JAVA中常见的数据结构介绍
Java基础-JAVA中常见的数据结构介绍 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.什么是数据结构 答:数据结构是指数据存储的组织方式.大致上分为线性表.栈(Stack) ...
- Java中常见的注解
Java中常见的注解 1.JDK自带的注解@Override @Deprecated @Suppvisewarnings 常见第三方注解 Spring:@Autowired @Service ...
- Java中常见的异常类型
一. Java中常见的异常类 异常类 说明 ClassCastException 类型准换异常 ClassNotFoundException 未找到相应类异常 ArithmeticException ...
- Java 中常见的 final 类
Java 中常见的 final 类 java.lang 包 public final class Boolean extends Object implements Serializable, Com ...
- java中常见的六种线程池详解
之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊Java 中常见的几种线程池,以及在jdk7 加入的 ForkJoin 新型线程池 首先我们列出Java 中的六种线程池如 ...
- java中的那些坑
最近准备换工作,为了少让人家鄙视,就要狠狠地藐视这些面试题目.找了本电子书,发了有好多坑,都是特别简单,但是很少有人做对的题目.面对这样的题目,我却有一种兴奋的感觉,也许是因为一直做着重复的工作没有新 ...
- java 中常见异常
1. Java.lang.NullPointerException 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的 ...
随机推荐
- BZOJ4278 [ONTAK2015]Tasowanie[后缀数组+贪心]
题目 求两数组归并后的数组最小字典序排列. 嘛,可能本人在贪心这块还是太弱了(或者说什么都弱),如果不知道是字符串题估计也想不起来用sa. 显然看得出归并时字典序小的那个数组先往里面加,这就是要比较两 ...
- T(n) = 25T(n/5)+n^2的时间复杂度
对于T(n) = a*T(n/b)+c*n^k;T(1) = c 这样的递归关系,有这样的结论: if (a > b^k) T(n) = O(n^(logb(a)));logb(a)b为底a ...
- 手工创建ASM Disk Groups、为 ASM Disk Groups 添加 disk
Groups 添加 disk 创建语法说明: 必选参数: (1) 指定disk group 的唯一名称 (不分区大小写) (2) 指定disk group 的冗余级别对于ASM 的镜像冗余,可以指定3 ...
- BZOJ1500:[NOI2005]维修数列
浅谈\(splay\):https://www.cnblogs.com/AKMer/p/9979592.html 浅谈\(fhq\)_\(treap\):https://www.cnblogs.com ...
- 查看SELinux状态&关闭SELinux
1. 查看SELinux状态 1.1 getenforce getenforce 命令是单词get(获取)和enforce(执行)连写,可查看selinux状态,与setenforce命令相反. se ...
- Python实例浅谈之五Python守护进程和脚本单例运行
一.简介 守护进程最重要的特性是后台运行:它必须与其运行前的环境隔离开来,这些环境包括未关闭的文件描述符.控制终端.会话和进程组.工作目录以及文件创建掩码等:它可以在系统启动时从启动脚本/etc/rc ...
- VijosP1100:加分二叉树
描述 设一个n个节点的二叉树tree的中序遍历为(l,2,3,…,n),其中数字1,2,3,…,n为节点编号.每个节点都有一个分数(均为正整数),记第i个节点的分数为di,tree及它的每个子树都有一 ...
- 五 python 发送邮件
需求: 系统中使用一个邮箱(这里用QQ)给其他邮箱发消息,用python完成,步骤如下: 1: 开启QQ邮箱的SMTP服务.设置-> 账号 2: 开启邮箱服务:这个需要手机验证,最后会给你一个授 ...
- ubuntu下caffe配置
http://blog.csdn.net/yhaolpz/article/details/71375762
- 实训随笔2:Git Gui——拯救菜鸟的工具
熟练使用git进行多人协作开发,是程序猿必备的专业技能之一,可惜我等实在太菜搞不来复杂的命令行. 幸好除了Git Bash还有一个Git gui存在——专门为了拯救我们这些菜鸡程序猿而存在的工具. 下 ...