Home > Enterprise >  How to use generics in Java when dealing with multiples heterogeneous objects?
How to use generics in Java when dealing with multiples heterogeneous objects?

Time:11-22

Let's say, I have two classes that look like this:

public class classA {
    private Boolean is_started;

    public classA(Boolean is_started) {
        this.is_started = started;
    }
    public Boolean getIs_started(){
        return this.is_started;
    }
}

public class classB {
    private String token;

    public classA(String token) {
        this.token = token;
    }
    public String get_token(){
        return this.token;
    }
}

I am calling those two classes from another class like this:

public class CallingClass {

    public void function1() {
        ClassA stepA = new ClassA(<some boolean>);
        commonFunction(stepA);
}
    public void function2() {
        ClassB stepB = new ClassB(<some string>);
        commonFunction(stepB);
}
    public <T> void commonFunction(Class<T> dataObject) {
        //An if statement that has a condition that only calls a function in classB {
            String token = dataObject.get_token();
        }
        //An if statement that has a condition that only calls a function in classA {
        Boolean is_started = dataObject.getIS_started();
        }
//It returns error : The method [get_token()/getIS_started()] is undefined for the type Class<T>

I want to make sure that I can call different objects without specifying them in the function. For example, I want to supply ClassA and ClassB as an argument to the commonFunction as in the example above. How do I make it happen with generics?

CodePudding user response:

You need some way to tie the classes together which says "this instance implements a method called getToken which returns some kind of result"

The simplest place to start would be a interface, for example...

public interface Tokenable<T> {
    public T getToken();
}

Then both ClassA and ClassB would need to implement this interface as required, for example...

public class ClassA implements Tokenable<Boolean> {

    private Boolean started;

    public ClassA(Boolean started) {
        this.started = started;
    }

    @Override
    public Boolean getToken() {
        return started;
    }

}

public class ClassB implements Tokenable<String> {

    private String token;

    public ClassB(String token) {
        this.token = token;
    }

    @Override
    public String getToken() {
        return token;
    }

}

And then you can communalise the call back...

public class CallingClass {

    public void function1() {
        ClassA stepA = new ClassA(false);
        commonFunction(stepA);
    }

    public void function2() {
        ClassB stepB = new ClassB("hello");
        commonFunction(stepB);
    }

    public <T> void commonFunction(Tokenable<T> dataObject) {
        T token = dataObject.getToken();
    }

}

Without providing some kind of common ancestor, you're not really going to be able to get it to work - Class doesn't define a getToken method, so you need some kind of common ancestor in order to call it (there is a "hacky" way to do it, but you really, really, really don't want to go down that rabbit hole)

CodePudding user response:

It could be that there's something I'm missing about your question because it's not entirely clear what you are trying to achieve but something doesn't seem quite right about the way you're trying to do this.

You have logic in commonFunction that behaves one way if the argument is one type and another way if the argument is the other type. It seems like what you really should do is have that logic inside ClassA and ClassB. So they should both implement some method that behaves one way inside ClassA and the other way inside ClassB. Then commonFunction can treat all arguments the same.

In general, if you are testing the type of an argument and triggering different behaviour in different cases then it's a pretty good indication that the behaviour really belongs inside those classes themselves, provided you are the one defining the classes which you are in this case.

  • Related