0

Class instance gets created in a per-type constant pool, when particular class(X) gets loaded.

javac compiles this syntax int.class to point to object that Integer.TYPE points to.

Below code, get access to parameterise(int) constructor of class X.

Class c = X.class;
Constructor cons = c.getConstructor(int.class);
cons.newInstance(10);

In the above code, I did not understand the role of int.class argument, under the hood.

Why getConstructor not designed to accept String type argument "int" instead of int.class? argument of Class.forName() is one example.

overexchange
  • 15,768
  • 30
  • 152
  • 347
  • please read question again – overexchange Jul 06 '15 at 08:19
  • possible duplicate of [Java: an object of what type is produced if the class literal is applied to the primitive type?](http://stackoverflow.com/questions/28688157/java-an-object-of-what-type-is-produced-if-the-class-literal-is-applied-to-the) – Joe Jul 06 '15 at 08:19
  • The code searches for a constructor in ``class X`` with one parameter of type ``int``. The "class" ``Integer.TYPE`` refers to the primitive integer here... – Binkan Salaryman Jul 06 '15 at 08:19
  • Why do we need class literal syntax as argument? String "int" argument would not suffice?? – overexchange Jul 06 '15 at 08:21
  • @overexchange Because java developers felt like reusing the ``class`` keyword at this point. Taking a more abstract perspective, ``class`` stands for a ``type`` - which includes primitives (for reflection uses, ``void`` is also considered a type) – Binkan Salaryman Jul 06 '15 at 08:24
  • p.s.: You may take a look at the documentation of ``java.lang.Class#isPrimitive()`` – Binkan Salaryman Jul 06 '15 at 08:26
  • 2
    Is the question, why have `int.class` as the argument and not `int`? I suspect the designers felt adding `.class` to the end made it clearer that this was a type literal rather than a cast missing a bracket or a variable which had been mistyped. – Peter Lawrey Jul 06 '15 at 08:31
  • Err, this question is nonsense. `int` would be a ***syntax error.*** – user207421 Jul 06 '15 at 08:45

2 Answers2

2

First of all, Class is a type dedicated to a certain purpose. There are a lot of classes, whose instances we could simply replace by a String and it would work if we accept a bit of ambiguity and possibly a performance loss. E.g. why use numbers instead of Strings containing their representation, or why use enums instead of their names? So having an instance of the dedicated type ensures that the creating, lookup, parsing or whatever action is required to get that instance has already successfully performed.

So having a Class object representing int.class, you known that you are referring to an existing type, something you can’t say about the String "int". A String parameter doesn’t necessarily refer to an existing type— it doesn’t even have to contain a valid name. And if you lookup a constructor having two int arguments, passing "int", "int" would imply to make the entire work of verifying the correctness and looking up the appropriate type twice. And so on…

And, since the restrictions of the Java programming language do not apply in the JVM, a String is ambiguous. It’s not clear whether "int" refers to a class named int or the primitive type int. Note that when you call loadClass("int") on a ClassLoader, it is always assumed that you are referring to a class named int as that method is not appropriate to look up primitive types. That’s the reason why int.class gets compiled to an access to Integer.TYPE, as primitive types can’t be looked up the same way as reference types.

Further, as already explained here, a name is ambiguous at runtime as there can be multiple classes having the same name, being defined by different ClassLoaders.

See JVMS §5.3 “Creation and Loading”:

At run time, a class or interface is determined not by its name alone, but by a pair: its binary name (§4.2.1) and its defining class loader.

And also JLS §12.2 “Loading of Classes and Interfaces”

Well-behaved class loaders maintain these properties:

  • Given the same name, a good class loader should always return the same class object.

  • If a class loader L1 delegates loading of a class C to another loader L2, then for any type T that occurs as the direct superclass or a direct superinterface of C, or as the type of a field in C, or as the type of a formal parameter of a method or constructor in C, or as a return type of a method in C, L1 and L2 should return the same Class object.

A malicious class loader could violate these properties. However, it could not undermine the security of the type system, because the Java Virtual Machine guards against this.

Community
  • 1
  • 1
Holger
  • 285,553
  • 42
  • 434
  • 765
1

int.class instead of Integer.TYPE is syntactic sugar the java compiler substitutes. A Class object is briefly said, an object holding meta information about a code-internal structure. But if we take a more abstract view at this, we can reuse that class to represent types: primitives, interfaces, and even void - which isn't a type but rather an identifier for methods with no return value. This reuse of Class has quite some advanges as in your example; consider following code:

public class X {
    public static void main(String args[]) throws Exception {
        X myX = X.class.getConstructor().newInstance();
        X myBigX = X.class.getConstructor(Integer.class).newInstance(0xCEED);
        X mySmallX = X.class.getConstructor(int.class).newInstance(10);
    }

    public X() {
        System.out.println("parameterless constructor called");
    }

    public X(Integer bigInteger) {
        System.out.println("object integer constructor called");
    }

    public X(int smallInteger) {
        System.out.println("primitive integer constructor called");
    }
}

If the reflection API developers had introduced for each method that takes a Class object as type identificator had to introduce a second one which handles types which are not exactly classes that would create unnecessary code duplication and unflexibility. Now, why had they decided to append .class to primitive type keywords to refer to ther respective Class pointers? As some people already stated, leaving away that part would lead to further confusion and syntax errors. As it is, the suffix is just continuing the pattern of writing a hard coded type.

Binkan Salaryman
  • 3,008
  • 1
  • 17
  • 29