0

I have a problem figuring out how to check which class a generic variable has at runtime. I have the following simplified class.

public class Link<E> {
    private final String type;
    private E e;
    
    public Link() {
        // TODO find out the class of 'E' and set 'type' to name it (i.e if E is a Float I want 'type = "Float"'
    }
    
    public Link(E e) {
        // TODO find out the class of 'E' and set 'type' to name it (i.e if E is a Float I want 'type = "Float"'
        this.e = e;
    }
    
    public synchronized E get() {return e;}
    
    public synchronized void set(E e) {
        this.e = e;
    }
    
    @Override
    public synchronized String toString() {
        return String.format("< %s > [ %s ]", type, (e == null ? "'null'" : e.toString()));
    }
}

With this class I can create an instance of it by the following command

Link<Integer> link = new Link<Integer>();

If I then call the toString method of this instance I want to receive the String "< Integer > [ 'null' ]" but I have no idea how to find out the type of the class in the constructor. Anyone knows how to do this?

Anju Maaka
  • 263
  • 1
  • 10

1 Answers1

0

This is not possible.

Generic definitions are erased at compile time and will E will be Object at runtime.

Generics do only provide a type safe way of developing a program.

If you want to bypass this, you can pass a Class<E> object to the constructor:

public Link(Class<E> cl) {
    //use cl to get the relevant information
}
        
public Link(Class<E> cl, E e) {
    //use cl to get the relevant information
    this.e = e;
}

You can obtain a Class<SomeClass> object by either writing SomeClass.class or creating an object of that class and executing the .getClass() method.

You could also try this constructor:

public Link(E e) {
    Class<? extends E> cl=e.getClass<>();
    //use cl to get the relevant information
    this.e = e;
}

However, the passed parameter may also be an instance of a subclass of E and getClass() will return the subclass instead of E.

dan1st
  • 12,568
  • 8
  • 34
  • 67
  • That feels kinda strange to me, that there is no way of finding out the class of E in an instance of Link. Once the instance has been created there is no way to change what E is right? The first case is probably the one I'll have to use, though I'd have preferred to get it automatically done. The later one won't work, since it's possible for 'e' to be null – Anju Maaka Aug 09 '20 at 18:26
  • The second one also has the problem of subclasses, as I said. E stays the same for an instance all the time, anyway but you can obviously create a setter(even if E kind of needs to stay the same, anyways). – dan1st Aug 09 '20 at 19:40