mercredi 15 mars 2023

Weird behaviour in custom generic class and reflection in Java

I have this custom generic class

@Component("box")
public class Box<T> {
    private T t; // T stands for "Type"

    public void set(T t) {
        this.t = t;
    }

    public T get() {
        return t;
    }

    @Override
    public String toString() {
        return "Box{" +
                "t=" + t +
                '}';
    }
}

In service class I have this method :

@Component("compo")
public class TempService {

    public Box<String> boxMeth(Box<String> stringBox)
    {
        System.out.println(Objects.nonNull(stringBox));
        System.out.println("Inside boxMeth!!!!!!");
        //System.out.println(stringBox.get());
        return stringBox;
    }

}

Inside main I have the following code using reflection :

TempService tmp =(TempService)apcon.getBean("compo");
        tmp.testMethod("1");
Box<Integer> box=(Box)apcon.getBean("box");
        box.set(10);
        Class classObj = tmp.getClass();
        Object obj = classObj.getDeclaredConstructor().newInstance();
        Method postHookMethod = obj.getClass().getMethod("boxMeth",Box.class);
        postHookMethod.invoke(obj,box); // getting allowed because of forceful action by reflection

        //tmp.testMethod(new Box<Integer>()); // not allowed

Now I know as bosMeth method allows Box of type String and by this line tmp.testMethod(new Box<Integer>()) I am trying to pass an Integer type compiler is throwing error.

But when I am setting value by reflection complier is allowing it. More interesting if I keep this line commented //System.out.println(stringBox.get()); compiler is not throwing any error.

So my questions are:

  1. How can Box <String> box can hold an object of type Box <Integer> when I am trying to pass the argument by reflection?

  2. If the value can be held then why there is an exception from this line //System.out.println(stringBox.get()); ? //class java.lang.Integer cannot be cast to class java.lang.String (java.lang.Integer and java.lang.String are in module java.base of loader 'bootstrap')





Aucun commentaire:

Enregistrer un commentaire