前言:
如今小伙伴们对“c语言char函数”大概比较注意,兄弟们都想要知道一些“c语言char函数”的相关知识。那么小编同时在网上搜集了一些关于“c语言char函数””的相关知识,希望大家能喜欢,朋友们快快来了解一下吧!作者 | 明明如月小角落
责编 | 屠敏
出品 | CSDN 博客
背景
下面给出一个例子,问输出的结果是多少:
public class IntTest {public static void main(String[] args) {
Integer a = 100, b = 100, c = 150, d = 150;
System.out.println(a == b);
System.out.println(c == d);
}
}
很多新手可能非常犹豫,有一些经验的同学可以回答出"标准"答案。
问原因则随口就说”Integer缓存了-128到127之间的整数对象“,为什么会缓存?还有其他答案?可能就不知道了。
what??? 难道这不是标准答案?还想咋地?
分析
运行
想知道答案很容易,直接运行,结果是 true ,false。
源码法
直接看源码, 我们知道声明整数时,会通过 java.lang.Integer#valueOf(int) 构造(不信可以断点)。
/*** Returns an {@code Integer} instance representing the specified
* {@code int} value. If a new {@code Integer} instance is not
* required, this method should generally be used in preference to
* the constructor {@link #Integer(int)}, as this method is likely
* to yield significantly better space and time performance by
* caching frequently requested values.
*
* This method will always cache values in the range -128 to 127,
* inclusive, and may cache other values outside of this range.
*
* @param i an {@code int} value.
* @return an {@code Integer} instance representing {@code i}.
* @since 1.5
*/
public static Integer valueOf(int i) {
if (i >= IntegerCache.low && i <= IntegerCache.high)
return IntegerCache.cache[i + (-IntegerCache.low)];
return new Integer(i);
}
通过源码和注释可以看到 如果是-128到127之间的整数,则会使用整数缓存对象,否则就new一个整形对象。
因此第一个是true,第二个是false。
反汇编
前面讲到了,用到了 再问一个问题 为什么调用了 java.lang.Integer#valueOf(int) ?
我们直接反汇编:javap -c IntTest
Compiled from "IntTest.java"public class com.chujianyun.common.int_test.IntTest {
public com.chujianyun.common.int_test.IntTest;
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 100
2: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
5: astore_1
6: bipush 100
8: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
11: astore_2
12: sipush 150
15: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
18: astore_3
19: sipush 150
22: invokestatic #2 // Method java/lang/Integer.valueOf:(I)Ljava/lang/Integer;
25: astore 4
27: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
30: aload_1
31: aload_2
32: if_acmpne 39
35: iconst_1
36: goto 40
39: iconst_0
40: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
43: getstatic #3 // Field java/lang/System.out:Ljava/io/PrintStream;
46: aload_3
47: aload 4
49: if_acmpne 56
52: iconst_1
53: goto 57
56: iconst_0
57: invokevirtual #4 // Method java/io/PrintStream.println:(Z)V
60: return
}
很明显四个Integer对象的构造使用了java/lang/Integer.valueOf函数。
那么除了上面的回答还有哪些更完善的回答呢?
我们继续看 java.lang.Integer.IntegerCache的源码
/*** Cache to support the object identity semantics of autoboxing for values between
* -128 and 127 (inclusive) as required by JLS.
*
* The cache is initialized on first usage. The size of the cache
* may be controlled by the {@code -XX:AutoBoxCacheMax=<size>} option.
* During VM initialization, java.lang.Integer.IntegerCache.high property
* may be set and saved in the private system properties in the
* sun.misc.VM class.
*/
private static class IntegerCache {
static final int low = -128;
static final int high;
static final Integer cache;
// 省略
}
可以看到可以通过设置虚拟机参数:XX:AutoBoxCacheMax=<size>或 -Djava.lang.Integer.IntegerCache.high=<high>
来设置缓存范围的最大值(包含)。
因此如果将最大值设置为150或者以上。则程序的答案就是 true, true。
另外缓存是 《Java语言规范》的要求,具体可以去语言规范里看。
总结
我们看一些文章的时候,不要止步于文章给出的标准答案,否则总是“背”文章,印象不深刻。
最好自己能够动手DEMO一下,能过亲自去源码里看一看,能够有自己的思考,才能学得更多。
研究Java相关问题除了多看源码外,还可以多反汇编,不要惧怕,一回生两回熟,慢慢就会乐此不疲。
总之希望本文能够给大家一些启发,养成读源码,反汇编等好的学习方法,更快进阶。
声明:本文为 CSDN 博主「明明如月小角落」的原创文章,版权归作者所有,如需转载请联系作者。
原文:
【END】
标签: #c语言char函数