【小家java】大杂烩---那些年我们一起躺过的坑

简介: 【小家java】大杂烩---那些年我们一起躺过的坑

相关阅读

【小家java】java5新特性(简述十大新特性) 重要一跃

【小家java】java6新特性(简述十大新特性) 鸡肋升级

【小家java】java7新特性(简述八大新特性) 不温不火

【小家java】java8新特性(简述十大新特性) 饱受赞誉

【小家java】java9新特性(简述十大新特性) 褒贬不一

【小家java】java10新特性(简述十大新特性) 小步迭代


##1、概述


此篇博文没有具体的主题,主要针对于平时开发过程中遇到的一些小问题的记录,并且大都从源码的角度去解释为什么会报错。并且此篇博文是持续更新中。。。


##2、栗子


1、包装类型的的> < =的比较


public static void main(String[] args) {
    Integer i = null;
    Integer i2 = null;
    System.out.println(i < i2); //java.lang.NullPointerException
}


包装类型能用比较运算符的根本原因:JDK5的自动拆箱。因此如果是是null的话,自动拆箱就报错了。所以在日常使用的时候一定要注意。特别是Interger和int比的时候,如果Interger为null,那必然空指针。从代码角度看是因为自动拆箱JVM会调用Interger的.intValue()方法,所以如果是null,就挂了


2、关于int值比较的一些问题


在日常编码中,经常会遇到Interger的比较问题(比如id相等),看下面例子

public static void main(String[] args) {
   Integer i1 = 100;
   Integer i2 = 100;
   System.out.println(i1 == i2); //true
   Integer i3 = 200;
   Integer i4 = 200;
   System.out.println(i3 == i4); //false
 }

我们知道,对象比较用==的话比较的是地址值,所以咱们看看两者的地址值哈。


public static void main(String[] args) {
    Integer i1 = 100;
    Integer i2 = 100;
    System.out.println(System.identityHashCode(i1)); //2093631819
    System.out.println(System.identityHashCode(i2)); //2093631819
    Integer i3 = 200;
    Integer i4 = 200;
    System.out.println(System.identityHashCode(i3)); //2074407503
    System.out.println(System.identityHashCode(i4)); //999966131
}


各位看官,应该看出端倪了吧,这就是为什么第一个是true,第二个为false的最直接原因,但还不是最根本原因,下面容我介绍一下最根本原因,Interger内部有如下代码:


image.png


同理Long里面一样


image.png


如图可以看出,Interger在初始化的时候内部就维护了一个缓存:-128到127对象都给Cache了,所以当我们向上转型这些对象时,没有new而是从缓存拿的,所以就是上面的答案。当然,我们必须清楚,其实JVM自动装箱调用了valueOf方法:

public static Integer valueOf(int i) {
    if (i >= IntegerCache.low && i <= IntegerCache.high)
        return IntegerCache.cache[i + (-IntegerCache.low)];
    return new Integer(i);
}

我们发现,没有new而是从缓存拿,因此内存地址值肯定一样的。所以可以很好理解下面这两个现象了:


public static void main(String[] args) {
     Integer i1 = new Integer(100);
     Integer i2 = new Integer(100);
     System.out.println(i1 == i2); //false 因为用了new关键字,一定开辟新内存的
     Integer i3 = new Integer(200);
     Integer i4 = new Integer(200);
     System.out.println(i3 == i4); //false
 }

这样比较也没有问题:


public static void main(String[] args) {
    int i1 = 100;
    int i2 = 100;
    System.out.println(i1 == i2); //true
    int i3 = 200;
    int i4 = 200;
    System.out.println(i3 == i4); //true
}


所以,综上所述,同类型的包装类型比较的时候,建议使用equals()方法。但是此处提醒一点:不同类型的equals肯定是false的,比如Interger和Long的对比,不要这么来:


public static void main(String[] args) {
     Integer i1 = 100;
     Long i2 = 100L;
     System.out.println(i1.equals(i2)); //false
 }


这个虽然值一样,但结果肯定false。这里我贴一处源码,大家就能了解了:


image.png


我们发现他们都重写了equals方法,而类型相同是第一必须。so,以后比较的时候一定要注意类型一致啊

3、intValue(),Integer.valueOf(String s)和Integer.parseInt(String s)有什么区别?


intValue()是把Integer对象类型变成int的基础数据类型; //一般由jvm自己调用

静态方法parseInt()是把String 变成int的基础数据类型;


静态方法valueOf()是把给定的String参数转化成Integer对象类型,依赖于parseInt()方法;


然后如果想得到一个小的Integer对象,但是Integer.valueOf的效率比new的效率高,因为valueOf有缓存。


综上所述,一般用Integer.parseInt(str),除非你要返回Integer类型,不然还有封装拆箱,性能多少会耗费些。

##3、使用场景



持续更新中。。。


##4、最后


整理出来的都是一些小细节,希望能帮助到大家


相关文章
|
存储 Java 编译器
【JavaSE】Java(五十):核心要点
1. JDK 和 JRE 有什么区别 JDK(Java Development Kit)和 JRE(Java Runtime Environment)是两个不同的软件包。它们共同提供了 Java 开发和运行时环境,但在功能和用途上存在一些区别。 JRE 包含 Java 运行时环境,它只用于执行 Java 应用程序,而没有提供任何开发工具。JRE 包括 JVM(Java 虚拟机)、Java 标准类库、Java 插件等组件,用户可以利用 JRE 去运行已经编写好的 Java 应用程序。 JDK 则是 Java 开发工具包,它除了包括 JRE 中的组件外,还提供了一系列的开发工具,例如编译器 j
|
Java C# uml
温习翻阅必备---java筑基期知识大全--“基础不牢,地动山摇”
温习翻阅必备---java筑基期知识大全--“基础不牢,地动山摇”
152 0
|
消息中间件 JavaScript 小程序
Java 20 正式发布,超神了。。
Java 20 正式发布,超神了。。
java202302java学习笔记第十九天-升级学生管理系统6
java202302java学习笔记第十九天-升级学生管理系统6 原
67 0
java202302java学习笔记第十九天-升级学生管理系统6
java202302java学习笔记第十九天-升级学生管理系统7
java202302java学习笔记第十九天-升级学生管理系统7
66 0
java202302java学习笔记第十九天-升级学生管理系统7
|
存储 Java 大数据
大数据学习记录---JAVA篇---面向对象基础部分
第二部分学习面向对象相关知识,这一部分其实不太熟悉,因为也不常写,记录一些知识点,以便后续回忆。
92 1
大数据学习记录---JAVA篇---面向对象基础部分
|
存储 Java 大数据
大数据学习记录---JAVA篇---基础语法部分
第一部分学到面向对象,把一些基础知识进行了学习,因为学过C和python,算是速过了一下基础,主要记录一些自己不熟悉的地方,以便日后可以回想起来。
93 1
大数据学习记录---JAVA篇---基础语法部分
|
消息中间件 算法 JavaScript
从 Java 8 升级到 Java 17 全过程,贼特么坑!
从 Java 8 升级到 Java 17 全过程,贼特么坑!
java202302java学习笔记第十九天-升级学生管理系统12代码
java202302java学习笔记第十九天-升级学生管理系统12代码
43 0
java202302java学习笔记第十九天-升级学生管理系统17全代码
java202302java学习笔记第十九天-升级学生管理系统17全代码
90 0