Correct way of converting String to Long in Java [duplicate]
Asked Answered
H

5

10

What is the most preferred way of converting a String to Long (the Object) in Java.

Long a = new Long(str);

OR

Long a = Long.parseLong(str);

Is there a correct way here because both seem to have the same level of readability and is it acceptable to add an extra step of autoboxing in the first method?

Hefty answered 29/9, 2016 at 14:57 Comment(4)
i am little curious, why would somebody want caching for a single object as question also suggest converting a single string object to longCiapha
@PavneetSingh Those things might happen in a loop or through a long period, Long instances might get put into collections, millions of instances. In this case (and when most of the values can actually be retrieved from the cache), caching can save a considerable amount of memory.Hills
@Hills first cache can't store million of instance plus it's range is very very limited and basically it's for java internal implementation not for enhancing performance ,for more clear information read my answer below (don't know why someone would down-vote it maybe did it on purpose ) :P:PCiapha
And although this is a dup, upvoted here; as it is simply a nicely written question for a newbie ;-)Phosphoric
H
17

Have a close look at the return types:

  1. Long.parseLong(String) returns a primitive long, so there will be re-boxing in this case: Long a = Long.parseLong(str);.
  2. new Long(String) will create a new Long object in every case. So, don't do this, but go for 3)
  3. Long.valueOf(String) returns a Long object, and will return cached instances for certain values -- so if you require a Long this is the preferred variant.

Inspecting the java.lang.Long source, the cache contains the following values (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);
    }
}
Hills answered 29/9, 2016 at 15:1 Comment(7)
So the best approach is to use Long.valueOf(str) :) ThanksHefty
@Hefty it seems not to me , check out my answer , might helpCiapha
i posted my answer just to guide others and though maybe for other good community member like you,to rectify your mistake instead you are trying to prove the official docs wrong which you can'tCiapha
@PavneetSingh Please be specific, about my "mistake" and where I would be trying to prove anything wrong.Hills
read my answer carefully and compare the points of your answer with mine ,you will find it yourselfCiapha
@PavneetSingh Your answer is hard to read and you keep on editing it every few hours. My time is precious, so I will not read it again.Hills
i just added little coding part for clarity since from this morning(12 hour ago) ,rest ok dude i can't change the down-vote trend on SO , SO is more like a battle-zone nowCiapha
A
10

The best approach is Long.valueOf(str) as it relies on Long.valueOf(long) which uses an internal cache making it more efficient since it will reuse if needed the cached instances of Long going from -128 to 127 included.

Returns a Long instance representing the specified long value. If a new Long instance is not required, this method should generally be used in preference to the constructor Long(long), as this method is likely to yield significantly better space and time performance by caching frequently requested values. Note that unlike the corresponding method in the Integer class, this method is not required to cache values within a particular range.

Generally speaking, it is a good practice to use the static factory method valueOf(str) of a wrapper class like Integer, Boolean, Long, ... since most of them reuse instances whenever it is possible making them potentially more efficient in term of memory footprint than the corresponding parse methods or constructors.


Excerpt from Effective Java Item 1 written by Joshua Bloch:

You can often avoid creating unnecessary objects by using static factory methods (Item 1) in preference to constructors on immutable classes that provide both. For example, the static factory method Boolean.valueOf(String) is almost always preferable to the constructor Boolean(String). The constructor creates a new object each time it’s called, while the static factory method is never required to do so and won’t in practice.

Allister answered 29/9, 2016 at 15:1 Comment(0)
C
3

I would like to suggest using Long.parseLong over every other option because :

  • Every other function i.e Long.valueOf, Long(string) relies on Long.parseLong method which works as a core method for every String to Long conversion.
  • As about caching, this will work when your input is only between -128 to 127 (see the Example below) so it's up to the coder that you want to call Long.parseLong directly or through Long.valueOf when your object is of String type.(obviously, use direct call).official docs and the source code link (why don't use Byte instead of Long then because cache won't save every long value even this range apply for Integers too)

From official docs

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));
}
  • About Long.valueOf returning a direct Wrapper object without creating new Long object is a false statement , as according to internally use of Long.parseLong (which returns a primitive long) , the primitive output of Long.parseLong will be converted to Wrapper object using by creating new object of Long class hence you wanna use direct Boxing or can call Long.valueOf=>Long.parseLong=>new Long

A little more about caching(if pass value is long) :

Cache is little helpful when you want to use == for equality check (like intern strings) with Object type. Long cache will only keep a static array of objects who's value is between -128 to 127 range inclusive so if your number is outside this range then you won't be able to use == operator for equality check (you don't believe, try following example)

Example:

    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);

Output:

false
false
true
true
true

So try to use equals for equality check.

Why cache required: because number between -128 to 127 inclusive need to be given identity for performance reasons of JLS (5.1.7) so cache is not for time/space efficiency in this case.

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);
}

Conclusion:

  • Use Long.parseLong.
  • Must use equals while working with Wrapper classes.
  • Cache for java mechanism works only if you want to use numbers between -128 to 127 with Wrapper classes.
Ciapha answered 29/9, 2016 at 17:4 Comment(5)
The caching will for sure work for valueOf, even when you provide a String and the conditions for the caching are met.Hills
@Hills you can analyse the source code , i wrote this post on concrete facts plus i have added the more details to prove my point .just because it proves your answer false doesn't mean you have to down vote it blindlyCiapha
@Hills read the conclusion first , there was some contradictory stuff which i forgot to remove but my conclusion states the true facts which you didn't even read and consider before down-votingCiapha
There are still invalid statements. Long.valueOf("1") will not create a new Long instance, but return a value from cache. Quote from the doc: "this method is likely to yield significantly better space and time performance by caching frequently requested values". What are you trying to proof?Hills
@Hills this doc belong to Long.valueOf(long input) so you are taking about the case where input value is long Long.valueOf(long l) not Long.valueOf(String l) so go and read the docs carefully and this also prove my one of many points you mentioned wrong in your answer. doc links to confirm and now you have a reason to remove your down-vote.Ciapha
R
2

From the source code:

public Long(String s) throws NumberFormatException {
    this.value = parseLong(s, 10);
}

In case you don't believe: enter image description here

Resht answered 29/9, 2016 at 15:0 Comment(0)
E
0

From the Javadoc:

Constructs a newly allocated Long object that represents the long value indicated by the String parameter. The string is converted to a long value in exactly the manner used by the parseLong method for radix 10.

Estrade answered 29/9, 2016 at 15:0 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.