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 这个异常大家肯定都经常遇到,异常的解释是"程序遇上了空指针",简单地说就是调用了未经初始化的对象或者是不存在的 ...
随机推荐
- jQuery bootstrap框架下重置下拉框选择
前端页面中下拉选择框采用bootstrap-select美化,如下图:
- The Django Book 2.0--中文版
Table of contents 2.0, English -> Chinese 第一章:介紹Django阅读 01 第二章 入门阅读 02 第三章 视图和URL配置阅读 03 第四章:模版阅 ...
- javacpp-FFmpeg系列之3: 像素图像数据转换(BGR与BufferdImage互转,RGB与BufferdImage互转,BufferdImage转Base64编码)
javacpp-ffmpeg系列: javacpp-FFmpeg系列之1:视频拉流解码成YUVJ420P,并保存为jpg图片 javacpp-FFmpeg系列之2:通用拉流解码器,支持视频拉流解码并转 ...
- 红黑树的C语言实现
rbtree.h #ifndef _RED_BLACK_TREE_H_ #define _RED_BLACK_TREE_H_ #define RED 0 // 红色节点 #define BLACK 1 ...
- C# 线程的暂停和恢复的 实现
我们可以通过ManualResetEvent类来实现. 声明, 初始化时不执行 private static ManualResetEvent _eventWorkList = new ManualR ...
- VS2008 查找失效怎么办
按Ctrl+F没有反应? visual studio 里 查找替换 显示不出来; 还能用 让他查找个不存在的文本还会弹出找不到的提示; 就是看不到 查找替换的操作框了; 问题解决方法: ...
- asp.net mvc 注册中的邮箱激活功能实现
基本流程图 注册页面就不再写出,现在将发送邮件的代码粘贴出来 public ActionResult SendEmial() { ; string validataCode = System.Gu ...
- 【240】◀▶IEW-Unit05
Unit 5 Education: Study Abroad 表格技巧讲解 1. Model1对应表格分析 This table shows the numbers of international ...
- Pycharm 设置TextStyle
之前在脚本中选择了一个字符串, PyCharm会"高亮"所有相同的字符串, 但是我不满意这个"高亮"的颜色,因为和背景色太相似了,所以需要做一下操作,修改这个& ...
- express前后的分离session的使用
express前后端分离session的使用 1.后端app.js中增加 app.all('*', function(req, res, next) { res.header("Access ...