10

Do they both return the same thing i.e Long Class. Actually i was using this within PrivilegedAccessor to pass as following

PrivilegedAccessor.invokeMethod(MyClass,
                "MyMethod", new Object[] { arg1, arg2 },
                new Class[] { long.class, Date.class });

Alternatively I can use

PrivilegedAccessor.invokeMethod(MyClass,
                    "MyMethod", new Object[] { arg1, arg2 },
                    new Class[] { Long.TYPE, Date.class });

Which is better to be used keeping in mind autoboxing / unboxing overheads.

** I am passing primitive long from the Test and even the tested method expects primitive long only.

Vivek Vermani
  • 1,934
  • 18
  • 45

4 Answers4

10

They both represent the long primitive type. They are exactly the same, even in the compiled bytecode. Sample program:

public class Main
{
   public static void main(String[] args) {
      Class<Long> c = Long.TYPE;
      Class<Long> c1 = long.class;
   }
}

Then, using javap -c Main:

c:\dev\src\misc>javap -c Main
Compiled from "Main.java"
public class Main {
  public Main();
    Code:
       0: aload_0
       1: invokespecial #1                  // Method java/lang/Object."<init>":
()V
       4: return

  public static void main(java.lang.String[]);
    Code:
       0: getstatic     #2                  // Field java/lang/Long.TYPE:Ljava/lang/Class;
       3: astore_1
       4: getstatic     #2                  // Field java/lang/Long.TYPE:Ljava/lang/Class;
       7: astore_2
       8: return
}
rgettman
  • 176,041
  • 30
  • 275
  • 357
2

These are exactly the same.

long.class == Long.TYPE; //always true
int.class == Integer.TYPE; //always true
float.class == Float.TYPE; // always true

The "TYPE" constants always have the value of the primitive class. I typically only use the TYPE thing, when I am not programming in Java, where the "int.class" syntax is not available.

About the reflection and boxing thing:

For reflection calls, primitive values are always boxed because Object arrays cannot contain primitive values. So it does not matter what you pass.

Also these two operations can return different methods:

Method fooInt = class.getMethod("foo", String.class, int.class);
Method fooInteger = class.getMethod("foo", String.class, Integer.class);

fooInt.equals(fooInteger); // false
AndiHofi
  • 39
  • 4
  • There is no primitive class. `public static final Class TYPE = (Class) Class.getPrimitiveClass("long");` This is a snippet from the JVM srouce code. And the `getPrimitiveClass` method is described as: `/* * Return the Virtual Machine's Class object for the named * primitive type. */ static native Class getPrimitiveClass(String name);` – lauksas Aug 04 '15 at 17:21
0

The most common way to do such a thing is to pass Long.class. You will rarely see long.class in production code.

The memory footprint is NEGLIGIBLE. You could run benchmarks with both methods, calling them 1kkk times, and you wouldn't notice much of a difference.

Georgian
  • 8,795
  • 8
  • 46
  • 87
  • Why would you pass a `Long.class` if you can pass a `long.class`? – assylias Jan 30 '14 at 18:12
  • Long is Object, so class, long is primitive. Even if the JVM makes the cast correctly "long.class" is not good idea. – Thrash Bean Jan 30 '14 at 18:15
  • 3
    There IS an important difference between `Long.class` and `long.class`: The first one is the class of the (reference) type `Long`, and the second is the class of the (primitive) type `long`. You have to be careful (and aware of) when to use the one or the other. The question was whether there is a difference between `long.class` and `Long.TYPE` - and the answer here is: No, there is no difference. – Marco13 Jan 30 '14 at 18:26
  • @Marco13 Can you provide different use cases? – Georgian Jan 30 '14 at 20:39
  • Actually, AndiHofi already showed one in his answer (http://stackoverflow.com/a/21464517/3182664) : Imagine you have a class with two methods: `void foo(Long x)` and `void foo(long x)`. In order to access either of them, you have to clearly say whether you want that with the `Long.class` argument type, or that with the `long.class` argument type. – Marco13 Jan 30 '14 at 21:20
-2

long is a primitive type and is not a Java Class. But Long is a type (extends Object) and thus is a Java Class. you can use either because Java has a Boxing and UnBoxing feature that converts one to another automatically for you. But beware, primitive type tends to consume less memory, but the Class type has very useful methods in it. you decide what is better for you.

Edit: Not sure why the down voting. As the article below says: "The class literal of a primitive type or void is equivalent to a static variable reference to a pre-installed primitive type descriptor" so long.class is not a Java class.

The Long.TYPE is assigned in the JVM source code as follows: public static final Class<Long> TYPE = (Class<Long>) Class.getPrimitiveClass("long");

and the method used is as follows:

static native Class getPrimitiveClass(String name);

so long.classis a pointer to a primitive variable which is not a java class.

long.class == Long.class is evaluated as FALSE.

http://www.cis.upenn.edu/~bcpierce/courses/629/jdkdocs/guide/innerclasses/spec/innerclasses.doc9.html

lauksas
  • 533
  • 7
  • 14