【小家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、最后


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


相关文章
|
XML 安全 Java
自定义PMD检测的类型集合(详解)
自定义PMD检测的类型集合(详解)
自定义PMD检测的类型集合(详解)
|
7月前
|
Linux 开发者 异构计算
英特尔显卡+魔搭社区,一行命令快速部署本地大模型
近期,Intel和魔搭合作,在魔搭社区上线了Ollama 英特尔优化版镜像,该镜像提供基于 IPEX-LLM 的 Ollama 英特尔优化版,开发者可在英特尔GPU (如搭载集成显卡的个人电脑,Arc 独立显卡等) 上直接免安装运行 Ollama。
533 3
|
9月前
|
数据采集 人工智能 移动开发
盘点人工智能在医疗诊断领域的应用
人工智能在医疗诊断领域的应用广泛,包括医学影像诊断、疾病预测与风险评估、病理诊断、药物研发、医疗机器人、远程医疗诊断和智能辅助诊断系统等。这些应用提高了诊断的准确性和效率,改善了患者的治疗效果和生活质量。然而,数据质量和安全性、AI系统的透明度等问题仍需关注和解决。
960 10
|
10月前
|
机器学习/深度学习 供应链 算法
量子计算:从理论到实践的跨越
量子计算基于量子力学原理,利用量子比特的叠加态和纠缠特性,展现出远超经典计算机的计算能力。本文从基本概念、发展历程、应用场景及未来挑战四个方面,全面介绍量子计算从理论到实践的跨越,展望其在优化问题、量子化学、机器学习等领域的广泛应用前景。
|
安全 C++
【C++ 泛型编程 进阶篇】:用std::integral_constant和std::is_*系列深入理解模板元编程(一)
【C++ 泛型编程 进阶篇】:用std::integral_constant和std::is_*系列深入理解模板元编程
619 1
|
11月前
|
安全 Shell Linux
内网渗透测试基础——Windows PowerShell篇
内网渗透测试基础——Windows PowerShell篇
444 0
|
SQL NoSQL Oracle
萌新妹纸不会写后端代码,还不是照样开发API速度贼快
萌新妹纸不会写后端代码,还不是照样开发API速度贼快
383 0
|
前端开发 定位技术
地图开发实战案例:高德地图的标注、信息窗口的实战实例
地图开发实战案例:高德地图的标注、信息窗口的实战实例
269 0
|
缓存 移动开发 运维
mPaaS云平台运维系列之—移动发布产品介绍
实时发布服务(Mobile Delivery Service,MDS)是 mPaaS 平台的核心基础服务组件之一,提供版本升级包、热修复包、H5 离线包的管理和发布服务,同时支持开关配置、白名单、发布规则管理功能。在客户端集成实时发布服务功能后,用户可以在 mPaaS 插件中生成新的包,然后在实时发布控制台发布新包,客户端收到新包并进行升级。实时发布服务还支持通过白名单进行灰度发布,可以使用高级过滤规则,比如指定机型,来进行更精准的灰度发布。
1193 0
mPaaS云平台运维系列之—移动发布产品介绍
|
算法 安全 数据挖掘
谈谈转录组测序基础知识及常见问题
转录组学(Transcriptomics),是一门在真整体水平上研究细胞中基因转录的情况及转录调控规律的学科,从RNA水平研究基因的表达情况。转录组测序是通过二代测序平台快速全面地获得某一物种特定细胞或组织在某一状态下的几乎所有的转录本及基因序列,可以用来研究基因表达量、基因功能、结构、可变剪接和预测新的转录本等等。转录组(transcriptome),是指特定生长阶段某组织或细胞内所有转录产物的集合,狭义上指所有mRNA的集合。
3261 0