Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass a parameterized class as an argument

Tags:

java

generics

My goal is to develop a class that can output an object of a specified class.

public class GetMe<T> {
    public T get() {
        Object obj = generateObject();
        return (T) obj;
    }
}

Now, I know this isn't possible due to erasure. So, we can pass in a class instance and use that to cast.

public class GetMe<T> {
    public GetMe<T>(Class<T> clazz) {
        this.clazz = clazz;
    }

    public T get() {
        Object obj = generateObject();
        return clazz.cast(obj);
    }
}

This works great! As long as the class isn't parameterized. If it is, then I've got a problem.

I'm not allowed to use List<String>.class. If I pass in a ParameterizedType (which in itself is difficult to generate), there's no cast method to use.

Is there a way out of this quagmire?

like image 301
Monkey Boson Avatar asked Feb 12 '11 19:02

Monkey Boson


People also ask

How do you pass a class object as a parameter in Java?

We have a method coypObject() which accepts an object of the current class and initializes the instance variables with the variables of this object and returns it. In the main method we are instantiating the Student class and making a copy by passing it as an argument to the coypObject() method.

Can we pass class as a parameter?

Yes, you can pass the object of a class inside a method as an argument.

Can we pass arguments to class in Java?

Arguments in Java are always passed-by-value. During method invocation, a copy of each argument, whether its a value or reference, is created in stack memory which is then passed to the method.

How do you pass a generic object in Java?

We use generics wildcard (?) with super keyword and lower bound class to achieve this. We can pass lower bound or any supertype of lower bound as an argument, in this case, java compiler allows to add lower bound object types to the list.


Video Answer


3 Answers

I think super type tokens may solve this problem for you.

like image 190
Matt McHenry Avatar answered Sep 22 '22 18:09

Matt McHenry


The problem with List<String> is that, because of erasure, it would at runtime indistinguishable from any other List<?>. The easiest way around this is to create a new class or interface which has the generic part "fixed", like

public interface StringList extends List<String> {
    /* nothing to see here */
}

This way you have a type token (the StringList.class object) which you can pass around at runtime and specifies exactly what you want, but without the need for generics at runtime.

like image 39
Waldheinz Avatar answered Sep 25 '22 18:09

Waldheinz


Here is just a small idea. I'm not really sure if it will fit in your context but nevertheless:

public class GetMe<T>
{
    public List<T> getList() {
        @SuppressWarnings("unchecked")
        List<T> result = (List<T>) new LinkedList(); 
        return result;
    }
}

Cheers!

like image 44
Lachezar Balev Avatar answered Sep 22 '22 18:09

Lachezar Balev