TheNewby
TheNewby

Reputation: 107

Java Convert Object Dynamic to Entity

I've created a function which requires a Parameter of type Object.

public void myFunction(Object obj){

}

Now I have 20 different Entities so the given Object Parameter can be of the type of this 20 entities. I'm searching for a way to cast this Object in the right Entity-type and get all values of it.

Right now I get the right type with this but I don't know how to cast it to this type and the fields are always 0.

System.out.println("Class: " + obj.getClass());//Gives me the right type
System.out.println("Field: " + obj.getClass().getFields().length);//Length is always 0

Upvotes: 3

Views: 17255

Answers (5)

Maurice Perry
Maurice Perry

Reputation: 9658

Since, your fields are private, you should either use getDelclaredFields, or getMethods and filter to keep only getters.

Note that getDeclaredFields only returns the fields of the top class. To get inherited fields, you must iterate with getSuperclass().

Upvotes: 0

Tschallacka
Tschallacka

Reputation: 28742

Not really the answer you asked, but I think you are looking for: The use case you described is what what interfaces are made for. I assume they share a set of methods you wish to utilise.

You define those methods in an interface,
then have your 20 classes implement that interface
then have your myFunction accept not Object obj, but interface obj and then call your methods via the interface functions.

interface IMyObject {
    public String[] getStuff() {
    }
    public void doStuff() {
    }

}

then have your "objects" implement it

class Foo implements IMyObject {
    public String[] getStuff() {
       return new String[10];
    }
    public void doStuff() {
       System.out.println("1+1 = 4");
    }
}
class Bar implements IMyObject {
    public String[] getStuff() {
       return new String[100];
    }
    public void doStuff() {
         System.out.println("5+1 = too hard");
    }
}
class Baz implements IMyObject {
    public String[] getStuff() {
       return new String[42];
    }
    public void doStuff() {
         System.out.println("1+1 = 2");
    }
}

Then have your myfunction accept the interface

public void myFunction(IMyObject obj){
    obj.doStuff();
}

The "contract" of IMyObject states that every IMyObject will have the methods getStuff and doStuff, so you can always call those.

public void something() {
   Bar myBar = new Bar();
   Baz myBaz = new Baz();
   myFunction(myBar);
   myFunction(myBaz);
}

Upvotes: 0

jlumietu
jlumietu

Reputation: 6444

You could try like this, using reflection to retrieve the declared fields of each Entity object:

 public class CastingTest {

    public static void cast(Object o) throws IllegalArgumentException, IllegalAccessException{
        Class<? extends Object> clazz = o.getClass();
        //clazz.cast(o);
        System.out.println(clazz.getName() + " >> " + clazz.getDeclaredFields().length);
        for(Field f: clazz.getDeclaredFields()){
            f.setAccessible(true);
            System.out.println( f.getName()  + "=" + f.get(o));
        }
    }

    public static void main(String args[]) throws IllegalArgumentException, IllegalAccessException{
        CastingTest.cast(new ClassA("A","B",1));
        CastingTest.cast(new ClassB("A","B",2.25));
    }
}

Testing models. ClassA:

public class ClassA {

    private String a;

    private String b;

    private int c;

    /**
     * @param a
     * @param b
     * @param c
     */
    public ClassA(String a, String b, int c) {
        super();
        this.a = a;
        this.b = b;
        this.c = c;
    }

}

Testing models. ClassB:

public class ClassB {

    private String varA;

    private String varC;

    private double value;

    /**
     * @param varA
     * @param varC
     * @param value
     */
    public ClassB(String varA, String varC, double value) {
        super();
        this.varA = varA;
        this.varC = varC;
        this.value = value;
    }

}

And the output:

com.test.ClassA >> 3
a=A
b=B
c=1
com.test.ClassB >> 3
varA=A
varC=B
value=2.25

Upvotes: 1

Adit A. Pillai
Adit A. Pillai

Reputation: 667

You can use reflection as follows:

assume that you have a data class like the following:

public class User {
    private String username;
    private String password;

    public void setPassword(final String password) {
        this.password = password;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public String getPassword() {
        return this.password;
    }

    public String getUsername() {
        return this.username;
    }

    public User() {
        // TODO Auto-generated constructor stub
    }
}

You can write a method to use reflection as follows:

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Test {
    public static void main(final String[] args) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
    IllegalAccessException, IllegalArgumentException, InvocationTargetException {

        User user = new User();
        user.setPassword("john");
        user.setUsername("doe");
        testMethod(user);
    }

    private static void testMethod(final Object obj) throws ClassNotFoundException, NoSuchMethodException, SecurityException,
        IllegalAccessException, IllegalArgumentException, InvocationTargetException {
        Class clzz = Class.forName(obj.getClass().getCanonicalName());
        Method method = clzz.getDeclaredMethod("getUsername");
        System.out.println(method.invoke(obj));
    }
}

Upvotes: 0

lubilis
lubilis

Reputation: 4170

public void myFunction(Object obj) {

    if (obj instanceof MyEntity) {

        MyEntity entity = (MyEntity) obj;
        // use entity instance as you need..
    }
}

Upvotes: 0

Related Questions