在Java中将 String
转换为 Long
(对象)的首选方法是什么。
Long a = new Long(str);
OR
Long a = Long.parseLong(str);
这里是否有正确的方法,因为两者似乎具有相同的可读性水平,并且在第一种方法中添加 autoboxing
的额外步骤是否可以接受?
答案 0 :(得分:15)
仔细查看返回类型:
Long.parseLong(String)
会返回原语 long
,因此在这种情况下会重新装箱:Long a = Long.parseLong(str);
。new Long(String)
会在每种情况下创建新 Long
对象。所以,不要这样做,而是去3)Long.valueOf(String)
会返回Long
个对象,并会返回某些值的缓存实例 - 因此,如果您需要Long
,则这是首选变体。检查java.lang.Long
源,缓存包含以下值(Sun JDK 1.8):
private static class LongCache {
private LongCache(){}
static final Long cache[] = new Long[-(-128) + 127 + 1];
static {
for(int i = 0; i < cache.length; i++)
cache[i] = new Long(i - 128);
}
}
答案 1 :(得分:8)
最好的方法是Long.valueOf(str)
,因为它依赖于Long.valueOf(long)
,它使用内部缓存使其更有效,因为如果需要,Long
的缓存实例将从{{1}重用包含-128
的内容。
返回表示指定long值的
127
实例。如果一个 新的Long实例不是必需的,这个方法一般应该是 优先使用构造函数Long
,因为这个方法是 可能会产生明显更好的空间和时间表现 缓存频繁请求的值。注意,不像 在Integer类中对应的方法,不需要此方法 缓存特定范围内的值。
一般来说,最好使用Long(long)
,static
,valueOf(str)
等包装类的Integer
工厂方法Boolean
。 ..因为只要有可能使它们在内存占用方面比相应的Long
方法或构造函数更有效,它们中的大多数都会重用实例。
Joshua Bloch撰写的Effective Java parse
摘录:
您通常可以使用 static来避免创建不必要的对象 工厂方法(第1项)优先于不可变的构造函数 提供两者的类。例如,静态工厂方法
Item 1
几乎总是优先于 构造函数Boolean.valueOf(String)
。构造函数创建一个新对象 每次调用它时,静态工厂方法永远不会 要求这样做,而不是在实践中。
答案 2 :(得分:2)
我建议使用Long.parseLong
覆盖所有其他选项,因为:
Long.valueOf
,Long(string)
都依赖于Long.parseLong
方法,该方法可作为每次String
到Long
转换的核心方法。Long.parseLong
的编码器当您的对象属于Long.valueOf
类型时,或者通过String
。(显然,使用直接调用)。official docs和source code link(为什么不使用Byte而不是Long因为缓存不会保存每个长值,即使这个范围也适用于整数)来自官方文档
public static Long valueOf(String s)
throws NumberFormatException
Returns a Long object holding the value of the specified String. The argument is interpreted as representing a signed decimal long, exactly as if the argument were given to the parseLong(java.lang.String) method. The result is a Long object that represents the integer value specified by the string.
**In other words, this method returns a Long object equal to the value of:**
new Long(Long.parseLong(s))
// internally calls to Long.valueOf when you pass string
public static Long valueOf(String s) throws NumberFormatException
{
return Long.valueOf(parseLong(s, 10));
}
Long.valueOf
返回直接Wrapper对象而不创建 new Long
对象是一个错误的声明,根据内部使用的{{1 (返回一个基元long),Long.parseLong
的基本输出将通过创建Long.parseLong
类的新对象转换为Wrapper
对象,因此你想使用直接Long
或者可以致电Boxing
关于缓存的更多信息(如果传递值很长):
如果要使用 == 进行具有对象类型的相等性检查(如实习字符串),则缓存很有用。长缓存只会保留一个静态数组的对象,其值在 Long.valueOf=>Long.parseLong=>new Long
范围内,所以如果您的数字超出此范围,那么您将无法使用 == 运算符用于等式检查(您不相信,请尝试以下示例)
示例:强>
-128 to 127
输出
Long b2=128L;
Long b3=128L;
Long aa=Long.valueOf("134");
Long ab=Long.valueOf("134");
System.out.println(b2==b3); // no cache for out of range values
System.out.println(aa==ab); // no cache for out of range values
System.out.println(aa.equals(ab)); // must use equals for equality check
System.out.println(b2.equals(b3));
b2=44; // between -128 to 127 it will work
b3=44;
System.out.println(b2==b3);
因此,请尝试使用false
false
true
true
true
进行相等检查。
为什么需要缓存:因为JLS (5.1.7)的性能原因需要为 -128到127 之间的数字提供身份,因此缓存不适用于时间/在这种情况下的空间效率。
equals
结论:
public static Long valueOf(long l) {
final int offset = 128;
if (l >= -128 && l <= 127) { // will cache , range is clearly seen
return LongCache.cache[(int)l + offset];
}
return new Long(l);
}
。Long.parseLong
类之间使用数字时,才能使用缓存for java机制。答案 3 :(得分:1)
来自源代码:
public Long(String s) throws NumberFormatException {
this.value = parseLong(s, 10);
}
答案 4 :(得分:0)
来自Javadoc:
构造一个新分配的Long对象,表示long String参数指示的值。该字符串将转换为a 完全按照parseLong方法使用的方式的long值 基数10。