一起谈.NET技术,C#之int挑战Java之Integer

简介:   本文涉及到一些JVM原理和Java的字节码指令,推荐感兴趣的读者阅读一本有关JVM的经典书籍《深入Java虚拟机(第2版)》,将它与我在《.NET 4.0面向对象编程漫谈》中介绍的CLR原理与IL汇编指令作个对比,相信读者会有一定的启发。

  本文涉及到一些JVM原理和Java的字节码指令,推荐感兴趣的读者阅读一本有关JVM的经典书籍《深入Java虚拟机(第2版)》,将它与我在《.NET 4.0面向对象编程漫谈》中介绍的CLR原理与IL汇编指令作个对比,相信读者会有一定的启发。而仔细对比两个类似事物的异同,是很有效的学习方法之一。

  今后我还将在个人博客上放出其他的文章,希望能帮助书的读者开拓视野,启发思考,大家一起探讨技术的奥秘。

  本文所述之内容仅代表个人之理解,任何疏漏及错误请直接回贴指出。

  1 奇特的程序输出

  前段时间,一个学生给我看了一段“非常诡异”的Java代码:

 
 
public class TestInteger {
public static void main(String[] args){
Integer v1
= 100 ;
Integer v2
= 100 ;
System.out.println(v1
== v2); // 输出:true
Integer w1 = 200 ;
Integer w2
= 200 ;
System.out.println(w1
== w2); // 输出:false
}
}

  让这个学生最困惑的是,为什么这些如此相似的代码会有这样令人意外的输出?

  我平时多使用C#,Java用得不多,初看到这段代码的输出,我也同样非常奇怪:怎么会这样呢?100和200这两个整型数值对Integer这个类有本质上的差别吗?

  为了弄明白出现上述现象的底层原因,我使用javap工具反汇编了Java编译器生成的.class文件:

1

  通过仔细阅读Java编译器生的字节码,我发现以下给Integer变量赋值的语句:

  Integer v1=100;

  实际上调用的是Integer.valueOf方法。

  而完成两个Integer变量比较的以下语句:

  System.Console.WriteLine(v1 == v2);

  实际生成的是if_acmpne指令。其中的a代表“address”,cmp代表“Compare”,ne代表“not equal”。

  这条指令的含义是:比较Java方法栈中的两个操作数(即v1与v2),看看它们是不是指向堆中的同一个对象。

  当给v1和v2赋值100时,它们将引用同一个Integer对象。

  那为什么当值改为200时,w1和w2就“翻脸了”,分别引用不同的Integer对象?

  秘密就在于Integer.valueOf方法。幸运的是,Java的类库是开源的,所以我们可以毫不费力地看到相关的源代码:

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

  一切真相大白,原来Integer在内部使用了一个私有的静态类IntegerCache,此类内部封装了一个Integer对象的cache数组来缓存Integer对象,其代码如下:

 
 
private static class IntegerCache {
static final Integer cache[];
// ……
}

  再仔细看看IntegerCache内部的代码,会看到它使用静态初始化块在cache数组中保存了[-128,127]区间内的一共256个Integer对象。

  当给Integer变量直接赋整数值时,如果这个数值位于[-128,127]内,JVM(Java Virtual Machine)就直接使用cache中缓存的Integer对象,否则,JVM会重新创建一个Integer对象。

  一切真相大白。 

目录
相关文章
|
23小时前
|
Java 机器人 程序员
解决Java中的NoSuchObjectException异常的技术指南
解决Java中的NoSuchObjectException异常的技术指南
|
21小时前
|
前端开发 Java 机器人
Java中的类加载器与热部署技术详解
Java中的类加载器与热部署技术详解
|
21小时前
|
存储 安全 Java
Java中的线程安全与同步技术
Java中的线程安全与同步技术
|
22小时前
|
Java 机器人 程序员
解决Java中的InstantiationException异常的技术指南
解决Java中的InstantiationException异常的技术指南
|
22小时前
|
算法 Java 机器人
解决Java中的NoSuchAlgorithmException异常的技术实践
解决Java中的NoSuchAlgorithmException异常的技术实践
|
1月前
|
开发框架 前端开发 .NET
C#编程与Web开发
【4月更文挑战第21天】本文探讨了C#在Web开发中的应用,包括使用ASP.NET框架、MVC模式、Web API和Entity Framework。C#作为.NET框架的主要语言,结合这些工具,能创建动态、高效的Web应用。实际案例涉及企业级应用、电子商务和社交媒体平台。尽管面临竞争和挑战,但C#在Web开发领域的前景将持续拓展。
|
1月前
|
SQL 开发框架 安全
C#编程与多线程处理
【4月更文挑战第21天】探索C#多线程处理,提升程序性能与响应性。了解C#中的Thread、Task类及Async/Await关键字,掌握线程同步与安全,实践并发计算、网络服务及UI优化。跟随未来发展趋势,利用C#打造高效应用。
|
1月前
|
开发框架 .NET Java
探索 C#编程的奥秘与魅力
【4月更文挑战第20天】C#是微软开发的现代、面向对象的编程语言,以其简洁语法、强大功能和跨平台支持脱颖而出。它支持自动垃圾回收、泛型、委托、LINQ,并广泛应用于桌面、Web、移动和游戏开发。C#拥有活跃的开发者社区和丰富的资源,是Unity游戏开发的首选语言。随着.NET Core,C#可在多个操作系统上运行,持续创新,未来发展潜力巨大。
|
1月前
|
存储 安全 网络安全
C#编程的安全性与加密技术
【4月更文挑战第21天】C#在.NET框架支持下,以其面向对象和高级特性成为安全软件开发的利器。本文探讨C#在安全加密领域的应用,包括使用System.Security.Cryptography库实现加密算法,利用SSL/TLS保障网络传输安全,进行身份验证,并强调编写安全代码的重要性。实际案例涵盖在线支付、企业应用和文件加密,展示了C#在应对安全挑战的同时,不断拓展其在该领域的潜力和未来前景。
|
1月前
|
人工智能 C# 云计算
C#编程的未来发展趋向
【4月更文挑战第21天】C#编程未来将深化跨平台支持,强化云计算与容器技术集成,如.NET Core、Docker。在AI和ML领域,C#将提供更丰富框架,与AI芯片集成。语言和工具将持续创新,优化异步编程,如Task、async和await,提升多核性能。开源生态的壮大将吸引更多开发者,共创更多机遇。

热门文章

最新文章