Java中将字符串转换为长字符串的正确方法

Java中将字符串转换为长字符串的正确方法,java,autoboxing,Java,Autoboxing,在Java中,将字符串转换为长(对象)的最首选方式是什么 或 这里是否有一种正确的方法,因为两者似乎具有相同的可读性级别,并且在第一种方法中添加额外的自动装箱步骤是否可以接受?源代码: public Long(String s) throws NumberFormatException { this.value = parseLong(s, 10); } 如果你不相信: 来自Javadoc: 构造一个新分配的长对象,该对象表示长对象 字符串参数指示的值。字符串被转换为 long值,与p

在Java中,将
字符串
转换为
(对象)的最首选方式是什么

这里是否有一种正确的方法,因为两者似乎具有相同的可读性级别,并且在第一种方法中添加额外的
自动装箱步骤是否可以接受?

源代码:

public Long(String s) throws NumberFormatException {
    this.value = parseLong(s, 10);
}
如果你不相信:

来自Javadoc:

构造一个新分配的长对象,该对象表示长对象 字符串参数指示的值。字符串被转换为 long值,与parseLong方法用于 基数10


仔细查看退货类型:

  • Long.parseLong(String)
    返回一个原语
    Long
    ,因此在这种情况下将重新装箱:
    Long a=Long.parseLong(str)
  • new Long(String)
    在任何情况下都将创建一个new
    Long
    对象。所以,不要这样做,而是选择3)
  • Long.valueOf(String)
    返回一个
    Long
    对象,并将返回某些值的缓存实例——因此,如果您需要
    Long
    ,这是首选的变体
  • 检查
    java.lang.Long
    源代码时,缓存包含以下值(Sun JDK 1.8):

    私有静态类LongCache{
    私有LongCache(){}
    静态最终长缓存[]=新长缓存[-128)+127+1];
    静止的{
    for(int i=0;i
    最好的方法是依赖于
    Long.valueOf(Long)
    ,它使用一个内部缓存,使其更高效,因为它将在需要时重用
    Long
    的缓存实例,从
    -128
    127

    返回表示指定长值的
    Long
    实例。如果 不需要新的长实例,通常应使用此方法 优先于构造函数
    Long(Long)
    ,因为此方法是 可能通过以下方式产生显著更好的空间和时间性能 缓存频繁请求的值。请注意,与 Integer类中的相应方法,此方法不是必需的 缓存特定范围内的值

    一般来说,使用包装类的
    static
    工厂方法
    valueOf(str)
    ,例如
    Integer
    Boolean
    Long
    。。。因为它们中的大多数在任何可能的情况下都会重用实例,这使得它们在内存占用方面可能比相应的
    parse
    方法或构造函数更有效


    摘自Joshua Bloch编写的
    项目1

    通常可以通过使用static避免创建不必要的对象 工厂方法(第1项)优先于不可变 提供这两者的类。例如,静态工厂方法
    Boolean.valueOf(String)
    几乎总是比 构造函数
    布尔值(字符串)
    。构造函数创建一个新对象 每次调用它时,静态工厂方法永远不会被调用 必须这样做,但在实践中不会这样做


    我建议在其他选项上使用
    Long.parseLong
    ,因为:

    • 其他每个函数,即
      Long.valueOf
      Long(string)
      依赖于
      Long.parseLong
      方法,该方法是每个
      字符串
      Long
      转换的核心方法
    • 关于缓存,当您的输入仅在-128到127之间时,这将起作用(请参见下面的示例),因此,当您的对象为
      String
      类型时,您要直接调用
      Long.parseLong
      或通过
      Long.valueOf
      调用的是由编码器决定的。(显然,使用直接调用)。和(为什么不使用Byte而不是Long-then,因为缓存不会保存每个长值,即使这个范围也适用于整数)
    来自官方文件

    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
      返回一个直接包装器对象而不创建
      新的Long
      对象是一个错误的语句,根据内部使用
      Long.parseLong
      (它返回一个原语Long),通过创建
      Long
      类的新对象,将
      Long.parseLong
      的原始输出转换为
      Wrapper
      对象,因此您可以使用直接
      Boxing
      或调用
      Long.valueOf=>Long.parseLong=>new Long
    关于缓存的更多信息(如果传递值很长):

    当您想使用=对对象类型进行相等性检查(如intern字符串)时,缓存没有什么帮助。长缓存将只保留一个静态对象数组,该数组的值介于
    -128到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
    
    因此,尝试使用
    equals
    进行相等性检查

    为什么需要缓存:因为出于性能原因,需要为-128到127之间的数字指定标识,所以在这种情况下,缓存不是为了时间/空间效率

    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);
    }
    
    公共静态长值of(长l){
    最终整数偏移=128;
    
    如果(l>=-128&&l我有点好奇,为什么有人想要缓存单个对象,因为问题还建议将单个字符串对象转换为long@PavneetSingh这些事情可能会在一个循环中发生,或者经过很长一段时间,长实例可能会被放入集合中,数百万个实例
        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
    
    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);
    }