对泛型使用 instanceof 和强制转换 以动物类为基础动物的各种颜色简化以可视动物为封闭类的动物园一个简单的测试测试结果

问题描述

我正在尝试创建一个函数,该函数接受具有一个类型参数 T 的参数化类的实例,然后使用反射查看其包络类的字段,检查这些字段是否为 T 类型,然后如果它们是,则对它们进行强制转换并对其进行处理。这是我到目前为止所拥有的:

 private <T> void someFunction(SomeClass<T> instance) throws illegalaccessexception {
            for(Field field : this.getClass().getDeclaredFields()){
                Object obj = field.get(this);
                // Todo: get parameter T from instance and store it in a variable named 'myClass'
                if(myClass.isinstance(obj)){
                    doSomething(instance,myClass.cast(obj))
                }
            }
        }

据我所知,为了在运行时执行此操作,您需要声明一个 Class 类型的变量并将 T 的类存储在其中,以便您可以使用 isinstance() 和 cast() 函数,但我是不确定如何正确执行此操作。

解决方法

短篇小说 - 缺少的部分

private <T extends SomeClass> void someFunction(SomeClass<T> instance) throws IllegalAccessException {
    for (Field field : this.getClass().getDeclaredFields()) {
        Object obj = field.get(this);

        Class<?> objClass = obj.getClass();
        if (objClass.isInstance(instance))
            doSomething(instance,(T) obj);
    }
  • 我们从对象中获取和存储类的位置,然后根据我们想要匹配的实例进行检查。
  • 我们使用 the wildcard ? 来表示未知类型,这样我们就不必弄清楚或指定类型。
  • 然后我们确保 doSomething 方法接受相同的泛型类型参数以允许类似的工作
    • 因此我们只需要转换为 T

作为一个整体,以动物为例

(是的,这是减少 :))

以动物类为基础

public abstract class Animal {

    protected Object color;

    protected Animal(Object color) {
        this.color = color;
    }

    protected Animal() {}

}

动物的各种颜色(简化)

无色动物(鬼?!)
public class NoColorAnimal extends Animal {

    // A null color
    public NoColorAnimal() {}

}
单色动物
public class SingleColorAnimal extends Animal {

    // A single String of color
    public SingleColorAnimal(String color) {
        super(color);
    }

}
多彩多姿的动物
public class MultiColorAnimal extends Animal {

    // An Array of colors
    public MultiColorAnimal(String... colors) {
        super(colors);
    }

}

以可视动物为封闭类的动物园

public class ZooAnimals {

    public MultiColorAnimal tiger = new MultiColorAnimal("black","orange");
    public SingleColorAnimal dolphin = new SingleColorAnimal("grey");


    public <T extends Animal> void viewAnimalIfPresent(Animal<T> animal) throws IllegalAccessException {
        for (Field field : this.getClass().getDeclaredFields()) {
            Object obj = field.get(this);

            Class<?> objClass = obj.getClass();
            if (objClass.isInstance(animal))
                view(animal,(T) obj,field.getName());
        }
    }

    private <T extends Animal> void view(Animal<T> animal,T obj,String name) {
        // TODO - Do something useful with these,but simply log them for now :)
        System.out.printf("Viewed a %s; the %s%n",obj.getClass().getSimpleName(),name);
    }

}

一个简单的测试

ZooAnimals zoo = new ZooAnimals();

    @Test
    public void test() throws IllegalAccessException {
        zoo.viewAnimalIfPresent(zoo.tiger);
        zoo.viewAnimalIfPresent(zoo.dolphin);
        zoo.viewAnimalIfPresent(new NoColorAnimal());
    }

测试结果

显示正确类型转换的测试控制台输出
Viewed a MultiColorAnimal; the tiger
Viewed a SingleColorAnimal; the dolphin

没有字段匹配无色动物,因此没有打印任何内容。