Guilherme Alves Lopes
Guilherme Alves Lopes

Reputation: 33

Downcast reference to runtime-known class

Is there any way by which I can cast a reference of type Object, assuming that the reference could point to any class I defined, to said defined class at runtime?

I've been trying to work it out and the code I came out with is:

public class SomeTestBench {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        myEntity a = new myEntity("Hello Code!");
        Receptacle cage = new Receptacle();
        cage.injectYourEntity(a);

        ((cage.itsClass) cage.theEntity).exertExistence();
    }

}

That unfortunately does not work, as the class argument to that cast must be static.

Rest of the code:

public class myEntity extends Object{
    String warcry;
    myEntity(String warcry){
        this.warcry = warcry;
    }
    public void exertExistence(){
        System.out.println(this.warcry);
    }
}

public class Receptacle {
    Object theEntity;
    Class itsClass;
    public void injectYourEntity(Object it){
        this.theEntity = it;
        this.itsClass = it.getClass();
    }
    public void prodIt(){
        System.out.println(theEntity.getClass());
    }

}

Upvotes: 0

Views: 62

Answers (2)

Andreas
Andreas

Reputation: 159260

To call a no-arg method named exertExistence() on an object of unknown type, you have three choices:

  1. Use generics. See answer by WJS.

  2. Use reflection:

    Receptacle cage = new Receptacle();
    cage.injectYourEntity(new myEntity("Hello Code!"));
    
    Method method = cage.itsClass.getMethod("exertExistence", null);
    method.invoke(cage.theEntity, null);
    
  3. Use an interface (recommended):

    Receptacle cage = new Receptacle();
    cage.injectYourEntity(new myEntity("Hello Code!"));
    cage.theEntity.exertExistence();
    
    interface MyInterface {
        void exertExistence();
    }
    
    class myEntity implements MyInterface {
        String warcry;
        myEntity(String warcry){
            this.warcry = warcry;
        }
        @Override
        public void exertExistence(){
            System.out.println(this.warcry);
        }
    }
    
    class Receptacle {
        MyInterface theEntity;
        public void injectYourEntity(MyInterface it){
            this.theEntity = it;
        }
    }
    

Upvotes: 0

WJS
WJS

Reputation: 40057

Why don't you just do this using Generics.

    public static void main(String[] args) {
        myEntity a = new myEntity("Hello Code!");
        Receptacle<myEntity> cage = new Receptacle<>();
        cage.injectYourEntity(a);

        cage.theEntity.exertExistence();
    }

//
//That unfortunately does not work, as the class argument to that cast must be static.
//
//Rest of the code:

class myEntity {
    String warcry;
    myEntity(String warcry){
        this.warcry = warcry;
    }
    public void exertExistence(){
        System.out.println(this.warcry);
    }
}

class Receptacle<T> {
    T theEntity;
    public void injectYourEntity(T it){
        this.theEntity = it;
    }
    public void prodIt(){
        System.out.println(theEntity.getClass());
    }

}

Upvotes: 2

Related Questions