有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

类如何在Java中处理多个异构对象时使用泛型?

比如说,我有两个类似的类:

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;
    }
}

我把这两门课叫做另一门课:

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>

我想确保我可以调用不同的对象,而无需在函数中指定它们。例如,我想提供ClassAClassB作为commonFunction的参数,如上面的例子所示。如何使用泛型实现这一点


共 (3) 个答案

  1. # 1 楼答案

    你的问题可能有我遗漏的地方,因为你不完全清楚你想要实现什么,但你尝试的方式似乎不太正确

    commonFunction中有一种逻辑,如果参数是一种类型,它会以一种方式运行,如果参数是另一种类型,它会以另一种方式运行。看起来你真正应该做的是在ClassA和ClassB中使用这种逻辑。因此,它们都应该实现某种方法,该方法在类A中以一种方式运行,在类B中以另一种方式运行。然后commonFunction可以对所有参数一视同仁

    一般来说,如果你正在测试一个参数的类型,并在不同的情况下触发不同的行为,那么这就很好地表明,这些行为确实属于这些类本身,前提是你定义了本例中的类

  2. # 2 楼答案

    您需要某种方法将这些类联系在一起,这表示“这个实例实现了一个名为getToken的方法,该方法返回某种结果”

    最简单的起点是一个interface,例如

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

    然后ClassAClassB都需要根据需要实现这个interface,例如

    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;
        }
    
    }
    

    然后你可以把回电话公之于众

    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();
        }
    
    }
    

    如果不提供某种共同祖先,你就不能真正让它工作——Class没有定义getToken方法,所以你需要某种共同祖先来调用它(有一种“黑客”的方法,但你真的,真的,真的不想进入兔子洞)

  3. # 3 楼答案

    对字面问题的直接回答是classAclassB的唯一超类型是Object,因此您的参数类型必须是Object,您可以使用instanceof来测试它是否是特定类型的实例,如果是,则转换为该类型以执行只能使用该类型执行的操作:

    public void commonFunction(Object dataObject) {
        if (dataObject instanceof classB) {
            String token = ((classB)dataObject).get_token();
        }
        if (dataObject instanceof classA) {
            Boolean is_started = ((classA)dataObject).getIS_started();
        }
    }
    

    然而,像这样使用instanceof是糟糕设计的证据。如果两种不同类型的逻辑是分开的,那么为什么要把它们放在同一个函数中呢?如果“token”和“is_start”应该表示相同类型的信息,那么将它们重构为接口中提供的相同方法,就像其他答案所建议的那样,更有意义