<T> T getInstance (final class <T>) why class <T> for both?

So, I am delving into Java and am interested in this use of parameters of this type.

<T>T getInstance

      

and then arg

Class<T> type

      

I'm a little confused here, because if we want a return type denoted like this T, then why not the same arg ... for example

private static String getInstance(String arg)

      

So I would understand that it would be

private static Class<T> getInstance(final Class<T> type)

      

So, I'm confused as to why the difference in an expression like return vs. argument

+3


source to share


5 answers


It is not necessary to have a return type the same as the type of the parameter, and in no way implies that this is a rule.

When the method is defined as

private static <T> T getInstance(final Class<T> type)

      

this means that the returned object will be of type T

, whereas the argument passed to this method is an instance of the typical type java.lang.Class

parameterized before T

.

This means that the method can be called like this:

String string = getInstance(String.class);

      



Therefore, this method takes an instance of the type Class

and returns an object of the type that matches this argument Class

.

On the other hand, when the method is defined as

private static <T> T getInstance(final T type)

      

then you need to pass an object of the type T

to get an instance. Imagine it will be called like this:

String string = getInstance("a");

      

Note that object "a" of type String

differs from String.class

type Class

.

+7


source


T

and Class<T>

completely different.

The first says: "an object of some type, T." The second says: "A type object java.lang.Class

that represents a class for some type T

."

In other words, here are two possible implementations:



Class<T> getInstance(Class<T> type) {
    return type;
}

T getInstance(Class<T> type) {
    return type.newInstance();
}

      

For example, if it T

is String

, then the first one will return String.class

, and the second one will return an empty string ""

.

+4


source


Think about what this method does: it returns instance

from Class

.

Using:

final String string = getInstance(String.class);

      

So what is the comeback - well it is String

. And what is the argument - it class String

is which is presented Class<String>

.

Thus, the method signature becomes:

String getInstance(Class<String> string);

      

Parameterizing String

as T

gives you the signature in your question.

+3


source


This is a trick that Java implemented to combat the chicken-and-egg problem where you have to create an object inside a generic type erasable method.

Class<T>

is made generic so that you can call it getInstance

type safe. Without <T>

in Class

all yours T

will be erased, leaving you with

Object getInstance() {...}

      

and has no way to get a reference to the class T

that was removed.

Transmit Class<T>

solves this problem because now the erased signature looks like this:

Object getInstance(Class cl) {...}

      

Although the type is erased again, you now have an object Class

that can be used as a "factory" to create new objects of the class T

. The fact that it Class<T>

is generic to the type it creates allows the Java compiler to do type checking, ensuring that a cast implicitly injected by the compiler will succeed at runtime.

+2


source


You must distinguish the class from your instance. This can be tricky because in Java, classes are also objects and therefore they also have a class (class class!). Say:

class Foo { ... }

      

  • The Foo instance is of type Foo;
  • The class itself Foo

    is an instance (only) of another class, exactly Class<Foo>

    .

So in the above description from left to right:

  • <T>

    - a general parameter, which makes a method a general method;
  • T

    - this is the return type: the method returns an instance of the class T

    ;
  • getInstance

    is the name of the method;
  • Class<T>

    means that you must pass as a parameter an instance (only) of the class T

    that the class itself has Class<Foo>

    .

You can access this singleton instance using an implicit static field Foo.class

. Every class declared has one, although you won't find it in the source code (tricky reflection issues).

Finally, why Class

is it common? Well, to have something like this:

package java.lang;

public final class Class<T> {
   public static T newInstance();
   ...
}

      

so it Foo.class.newInstance()

returns a Foo

, Baz.class.newInstance()

returns a Baz

and so on. Gently, right?

+2


source







All Articles