7

I couldn't find any information about this when searching StackOverflow or Google, and I've got some coworkers who disagree with my preference for how to initialize a simple Long variable.

Is there any reason to use one of these formats over the other?

Long foo = (long) 0; // First way of doing it
Long bar = 0L; // Second way of doing it

I'm most interested if anyone knows if there is an efficiency difference here.

The reason I prefer the second way is because you can specify values less than Integer.MIN_VALUE and greater than Integer.MAX_VALUE, whereas Eclipse would complain with something along the lines of "The literal 10000000000 of type int is out of range" if you used the first way here.

  • Personally I prefer 0L, but be aware that also a small letter l is possible which has the big disadvantage to be almost unreadable (looks almost like digit 1). Maybe that is the reason why some people prefer the casting. – Meno Hochschild Mar 12 '14 at 14:42
  • possible duplicate of [Initialize a long in Java](http://stackoverflow.com/questions/6834037/initialize-a-long-in-java) – Chris Forrence Mar 12 '14 at 14:42

4 Answers4

13

There is no difference (except you mentioned). Compiler is smart enough. If I compile following class:

public class Test {
    public static void main(String[] args) {
        Long foo = (long) 0;
        Long bar = 0L;
    }
}

And then decompile them:

$ javap -c Test.class

Compiled from "Test.java"
public class Test {
  public Test();
    Code:
       0: aload_0       
       1: invokespecial #1                  // Method java/lang/Object."<init>":()V
       4: return        

  public static void main(java.lang.String[]);
    Code:
       0: lconst_0      
       1: invokestatic  #2                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
       4: astore_1      
       5: lconst_0      
       6: invokestatic  #2                  // Method java/lang/Long.valueOf:(J)Ljava/lang/Long;
       9: astore_2      
      10: return        
}

I don't see any difference. Use one which is look better for you or corresponds to the conventions.

To verify decompiler I compile this two lines independent and then calculate checksums:

$ sha1sum Test.class_L Test.class_long
292a93b6433b5a451afdb41bd957667c91eebf23  Test.class_L
292a93b6433b5a451afdb41bd957667c91eebf23  Test.class_long
Anton Bessonov
  • 9,208
  • 3
  • 35
  • 38
  • 2
    This is the better answer: anything else is imagination or opinion. – CPerkins Mar 12 '14 at 14:49
  • @cperkins Please explain how they are imagination or opinion. – Sotirios Delimanolis Mar 12 '14 at 14:52
  • 1
    @Sotirios Delimanolis because you don't know how you compiled code look like before you compile. To be sure you must decompile code and look what happen and not try to guess it. – Anton Bessonov Mar 12 '14 at 14:57
  • 1
    The other answers are not guesses. They state exactly what is written in the JLS. A compiler must follow the JLS for it to be java-compliant. – Sotirios Delimanolis Mar 12 '14 at 15:01
  • @AntonBessonov - replace `0` in your first example with `10000000000`. While the compiler *is* smart enough to see that the only term in the expression is a `long`, it will reject an attempt to cast a value that is not within `int` range. – kdgregory Mar 12 '14 at 15:35
  • @kdgregory Of course! But this is not related to the question, because OP pointed this himself ;o) – Anton Bessonov Mar 12 '14 at 15:41
  • @SotiriosDelimanolis we are not meant to have conversations in the comments, so this will be my last contribution to the thread. Anton Bessonov has given my respons for me: until we check to see what the JVM will do, we can't know which way is better. Consider: the currently top-voted answerer actually (literally) wrote: "`I imagine the difference is negligible...`". – CPerkins Mar 12 '14 at 17:02
  • 1
    @CPerkins - In this case it's not what the JVM will do, but what one particular compiler will do. There's no guarantee that any other compiler will make this optimization. And in the *general* case, it's not a correct way to initialize a `long` (which is what the title asks) because it cannot represent the full range of values. – kdgregory Mar 12 '14 at 23:59
  • @CPerkins The JLS states that `0` is an integer literal, so its value is an `int`. Casting that value with `(long)` creates [_a widening primitive conversion_](http://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.5). A compiler can determine that that conversion is unnecessary in this case and generate a `long` directly. This is because `A widening primitive conversion from an integral type to another integral type does not lose any information at all`. This might not stand for other compilers. Other may issue a `i2l` bytecode instruction to do the casting. – Sotirios Delimanolis Mar 13 '14 at 04:50
10
Long foo = (long) 0; // First way of doing it

This way will create an int then cast it to a long.

Long bar = 0L; // Second way of doing it

This is a long literal, so it will only create a long.

I imagine the difference is negligible, but it would be quicker to create a long than to create an int then cast to long.

Edit

As you correctly said, the first way will only allow you to convert an int to a long, which means that in one line, you can only ever create a long the size of an int.. which is pointless and a waste of memory.

christopher
  • 26,815
  • 5
  • 55
  • 89
  • 1
    The compiler doesn't do a cast for the first one, as demonstrated in @Anton Bessonov's answer. But, the second way should be preferred for the reason you gave in your edit. – GriffeyDog Mar 12 '14 at 15:04
2

(long) 0 casts an int to a long. 0L is a long. So if you want to use a long, use one.

1

One difference which isn't mentioned is that the compiler will reject a numeric literal which is larger than 2147483647 but doesn't have an L suffix. If there are semantic reasons why one needs a literal to be processed as type long rather than int, but the code would malfunction if given any value larger than 2147483647, casting an unsuffixed literal would retain the constraint on the value while forcing the type to be processed as long. Such a thing might be appropriate, for example, if a value would be multiplied by 256 and then later divided by 256, and if the result of such division would need to fit in an int.

supercat
  • 77,689
  • 9
  • 166
  • 211