最近在公司参与一个项目,项目挺大,耗时一年左右,具体业务就不说了。。。
之后在项目开发将近结束时,公司用Coverity工具对整体代码进行了检视,结果发现了N多问题,好多都是自己不注意的细节,在感叹此工具的强大的同时,问了下项目经理这个工具的价格,告知,30万$ !!! 纳尼
神马!尼玛
代码检视这块儿和findbug也差不多啊, 这也忒狠了点吧。。。
不扯淡了,步入正题。
在检视过程中,提到如下一个问题,就是在我们代码中用new Integer(a) 的地方,好多都提示说Ineffective way, use Integer.valueOf(int) intead. 一时感觉好奇,翻开源码查看,没有查出啥究竟,然后后来利用debug模式进入源码调试才发现,原来里面的实现也大有天地。。。
首先查看valueof(int) 方法的实现:
-
-
-
-
-
-
-
-
-
-
-
-
-
-
public
static
Integer valueOf(
int
i) {
-
if
(i >= -
128
&& i <= IntegerCache.high)
-
return
IntegerCache.cache[i +
128
];
-
else
-
return
new
Integer(i);
-
}
/**
* Returns a <tt>Integer</tt> instance representing the specified
* <tt>int</tt> value.
* If a new <tt>Integer</tt> 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.
*
* @param i an <code>int</code> value.
* @return a <tt>Integer</tt> instance representing <tt>i</tt>.
* @since 1.5
*/
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类的一个内部私有类。
-
private
static
class
IntegerCache {
-
static
final
int
high;
-
static
final
Integer cache[];
-
-
static
{
-
final
int
low = -
128
;
-
-
-
int
h =
127
;
-
if
(integerCacheHighPropValue !=
null
) {
-
-
-
int
i = Long.decode(integerCacheHighPropValue).intValue();
-
i = Math.max(i, 127
);
-
-
h = Math.min(i, Integer.MAX_VALUE - -low);
-
}
-
high = h;
-
-
cache = new
Integer[(high - low) +
1
];
-
int
j = low;
-
for
(
int
k =
0
; k < cache.length; k++)
-
cache[k] = new
Integer(j++);
-
}
-
-
private
IntegerCache() {}
-
}
private static class IntegerCache {
static final int high;
static final Integer cache[];
static {
final int low = -128;
// high value may be configured by property
int h = 127;
if (integerCacheHighPropValue != null) {
// Use Long.decode here to avoid invoking methods that
// require Integer's autoboxing cache to be initialized
int i = Long.decode(integerCacheHighPropValue).intValue();
i = Math.max(i, 127);
// Maximum array size is Integer.MAX_VALUE
h = Math.min(i, Integer.MAX_VALUE - -low);
}
high = h;
cache = new Integer[(high - low) + 1];
int j = low;
for(int k = 0; k < cache.length; k++)
cache[k] = new Integer(j++);
}
private IntegerCache() {}
}
至此,谜底基本解开,原来IntegerCache相当于做了一个缓存,在第一次被调用时,首先初始化生成了从-128到127共256个对象的数组,在以后凡是在这个范围内的int值都可以直接从此缓存中取,而不在再次生成Integer对象,大大提高了对象的利用率。
然后我做了一个测试类,来测试二者真正的效率区别:
-
public
static
void
testEfficiency(){
-
int
count =
10000000
;
-
long
t1 = System.currentTimeMillis();
-
for
(
int
i =
0
; i < count; i ++){
-
-
int
a =
new
Integer(i%
128
*(i%
2
==
0
?-
1
:
1
));
-
-
}
-
long
t2 = System.currentTimeMillis();
-
for
(
int
i =
0
; i < count; i ++){
-
int
b = Integer.valueOf(i%
128
*(i%
2
==
0
?-
1
:
1
));
-
}
-
long
t3 = System.currentTimeMillis();
-
System.out.println("Time of new Integer() method:"
+(t2-t1)+
"ms"
);
-
System.out.println("Time of Integer.ValueOf:"
+(t3-t2)+
"ms"
);
-
}
public static void testEfficiency(){
int count = 10000000;
long t1 = System.currentTimeMillis();
for(int i = 0; i < count; i ++){
int a = new Integer(i%128 *(i%2 == 0?-1:1));
}
long t2 = System.currentTimeMillis();
for(int i = 0; i < count; i ++){
int b = Integer.valueOf(i%128 *(i%2 == 0?-1:1));
}
long t3 = System.currentTimeMillis();
System.out.println("Time of new Integer() method:"+(t2-t1)+"ms");
System.out.println("Time of Integer.ValueOf:"+(t3-t2)+"ms");
}
输出结果:
-
Time of
new
Integer() method:125ms
-
Time of Integer.ValueOf:94ms
Time of new Integer() method:125ms
Time of Integer.ValueOf:94ms
二者似乎区别多大,不过这说明JDK虚拟机的效率比较高,
然后将这两种方式单独封装到两个方法中,利用两个程序进行调试,然后再看下javaw.exe所占的内存,区别就出来了。。。大家可以自己试一下,为了查看内存,可以将程序sleep 20s来查看, 我本机的测试结果:
new Integer方式:13 516K
Integer.valueOf方式:8 852K.
相差4664K.
实验基本到此结束,但是学习却只是一个开始,在实际项目中也可以参考此种实现方式,懒加载和缓存的思想。
转自:http://feikiss.iteye.com/blog/1285283
分享到:
相关推荐
在Java中,Integer.ValueOf()方法是一个非常重要的方法,它可以将整数类型的值转换为Integer对象。下面我们就来详细了解一下这个方法的实现原理和使用方式。 首先,让我们来看一下Integer.ValueOf()方法的源码: `...
Java 中的 Integer 类中有两个静态方法,Integer.valueOf(String s) 和 Integer.parseInt(String s),它们都可以将字符串转换为整型,但它们之间有着很大的区别。 首先,Integer.parseInt(String s) 将会返回 int ...
Java 中 String 类型转换方法 Java 中 String 类型转换方法是一种常见的编程...Java 中 String 类型转换方法有多种形式,每种形式都有其特点和应用场景,掌握这些方法可以帮助开发者更好地进行数据类型之间的转换。
Integer integer = Integer.valueOf(str); 三、将 int 转换成 String 将 int 转换成 String 可以使用以下三种方法: 1. 使用 String.valueOf() 方法 String s = String.valueOf(i); 2. 使用 Integer.toString()...
在Java编程语言中,将`Integer`对象转换为基本数据类型`int`有两种常见的方法:`Integer.parseInt()`和`Integer.valueOf()`。理解这两种方法的区别和应用场景对于编写高效且正确的Java代码至关重要。 首先,我们来...
在Java中,`Integer.parseInt()` 和 `Integer.valueOf()` 方法默认将字符串转换为32位有符号整数。这意味着它们能够处理的范围是 `-2^31` 到 `2^31 - 1`,即 `-2147483648` 到 `2147483647`。因此,当试图将 `'...
当使用valueOf方法创建Integer对象时,如果值在缓存范围内,会直接从缓存中获取,否则新建一个对象。例如: ```java Integer x = new Integer(123); // 新建对象 Integer y = new Integer(123); // 新建对象,即使...
### Integer类的使用方法详解 在Java编程语言中,`Integer`类是一个...总之,`Integer`类提供了丰富的功能,使得在Java中处理整数更加方便和高效。掌握这些方法的应用,对于编写高质量、高效率的Java程序至关重要。
Integer i = new Integer(xxx) 和 Integer i = xxx 的区别在于,前者创建了一个新的对象,而后者可能会从常量池中返回该对象的引用。如果 xxx 的值在 -128 到 127 之间,那么 Integer i = xxx;就可能会从常量池中...
Integer iVal = Integer.valueOf(100); Long lVal = Long.valueOf(100L); Boolean bVal = Boolean.valueOf(false); ``` ##### 四、特定包装器类 - **`Boolean`类**: - 用于处理需要将`boolean`原始类型转换为...
十进制与八进制与十六进制之间的转换可以使用 Integer.toOctalString() 方法、Integer.toHexString() 方法和 Integer.valueOf() 方法。例如: ```java int dec = 150; String octal = Integer.toOctalString(dec);//...
此外,它们还包含一些常量,如MAX_VALUE、MIN_VALUE、NaN、POSITIVE_INFINITY和NEGATIVE_INFINITY,以及比较和转换方法,例如compareTo()、parseFloat()、valueOf()等。 示例代码: ```java Float f = new Float(3....
为了确保程序的正确性和效率,掌握Java中的类型转换方法至关重要。本文将详细介绍Java中常见的类型转换操作,包括数字类型与字符串之间的相互转换、十进制与二进制/十六进制之间的转换、ASCII码与字符之间的转换以及...
在 Java 编程语言中,数据类型转换是非常重要的,良好的数据类型转换可以提高程序的效率和可读性。在本文中,我们将详细介绍 Java 中的数据类型转换,包括字符串转换为整数、整数转换为字符串、浮点数转换为字符串等...
list.remove(Integer.valueOf(2)); // 移除值为2的第一个元素 // 查询元素 boolean contains = list.contains(1); // 检查列表中是否包含特定元素 // 其他操作 list.clear(); // 清空列表 int size = list.size();...
实际上,Java编译器会自动执行`Integer.valueOf(40)`方法,这是由于Java的自动装箱机制。`Integer.valueOf()`方法的目的是优化性能,因为它利用了对象池机制。对象池在`Integer`类中以内部类`IntegerCache`的形式...
Integer integer = Integer.valueOf(intStr); return integer.intValue(); } // 将整数类型转换为字符串类型 public static String intToString(int value) { Integer integer = new Integer(value); return...
通过Integer.valueOf()方法获取这些范围内的数值时,会从缓存池中直接获取或复用对象,而不是每次都创建新的对象。例如: ```java Integer x = new Integer(123); // 创建新对象 Integer y = new Integer(123); // ...
在Java中,我们可以直接声明Integer i = 10,这将自动装箱变为Integer i = Integer.valueOf(10);同时Integer i 也可以自动拆箱为 i.intValue()。 知识点2:Integer.valueOf()方法 Integer.valueOf()方法会将int...