Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing parameterized Class instance to the constructor

Tags:

java

generics

I have lost in the Jungle of Generics, please help me :) I have something like this:

public class BaseClass<TYPE> {
    public BaseClass(Class<TYPE> clazz) {};
}

public class FirstLevelClass<REFRESHABLE 
    extends RefreshableInterface> extends BaseClass<REFRESHABLE> {

    public FirstLevelClass(Class<REFRESHABLE> clazz) {
        super(clazz);
    };
}

public class Argument<T extends AnyOtherClass> 
    implements RefreshableInterface {

    public refresh() {}
}

pulbic class ProblematicClass 
    extends FirstLevelClass<Argument<AnyOtherClassDescendant>> {

    public ProblematicClass() {
        //Compiler error: Constructor 
        //FirstLevelClass<Argument<AnyOtherClassDescendant>>(Class<Argument>) is undefined
        super(Argument.class); 
    }
}

As far as I think, the compiler should accept Argument since it implements RefreshableInterface.

  • Why do I get this error?
  • How can I make the ProblematicClass working?

ps: if you have better title for this, please change it. I could not make up better.

like image 345
Gábor Lipták Avatar asked Mar 03 '14 17:03

Gábor Lipták


People also ask

How do you pass a parameterized constructor?

You can only define the coursebookname variable one time (which is when you specify the type). Remove the String designation from before the variable name when you pass it to the Person constructor and it should work fine.

Can we pass parameters to constructor?

You can use any data type for a parameter of a method or a constructor. This includes primitive data types, such as doubles, floats, and integers, as you saw in the computePayment method, and reference data types, such as objects and arrays.

What is meant by parameter passing constructors give example?

Parameterized Constructor – A constructor is called Parameterized Constructor when it accepts a specific number of parameters. To initialize data members of a class with distinct values. In the above example, we are passing a string and an integer to the object.

What happens if you implement a parameterized constructor in class?

If there is any one parametrized Constructor present in a class, Default Constructor will not be added at Compile time. So if your program has any constructor containing parameters and no default constructor is specified then you will not be able to create object of that class using Default constructor.


1 Answers

Issue is, your constructor expects a Class<T>, and T in your code is inferred as Argument<AnyOtherClassDescendant>.

So, you should pass a Class<Argument<AnyOtherClassDescendant>>, and you're passing Class<Argument>. But you can't pass that Class instance directly, as you cannot do Argument<AnyOtherClassDescendant>.class.

You can however, solve the issue by typecasting the class to required instance:

public ProblematicClass() {
    super((Class<Argument<AnyOtherClassDescendant>>)(Class<?>)Argument.class); 
}

Note, how you've to typecast Class<Argument> first to Class<?>, and then the resultant type to Class<Argument<AnyOtherClassDescendant>>. There is no simple way to achieve that.

The reason behind this is, there is only a single Class instance for all parameterized instantiation of a generic type, that is associated with the class itself. A single compilation unit of a generic type, compiles to just a single class file. I guess this is different in how C++ implements templates. There you get different machine codes for different instantiation.

So, if you execute the below code, you'll get true as output:

List<String> strList = new ArrayList<String>();
List<Integer> intList = new ArrayList<Integer>();

boolean isSameClassInstance = strList.getClass() == intList.getClass();
System.out.println(isSameClassInstance);
like image 193
Rohit Jain Avatar answered Oct 29 '22 00:10

Rohit Jain