如何将.class-type参数传递给方法

时间:2018-04-19 11:44:36

标签: java inheritance polymorphism

PersonenGenerator{
Set<Person> personSet = new HashSet<>();

public void printPersonTypeSet(Class clazz){ //pass a class that inherits from the class Person as a parameter
    for(Person instance : personSet){    
        if (instance instanceof clazz) System.out.println(instance);
    } // check if instance of Class Person are stored in personSet. If so, print said instance
}


public class Student extends Person{
...
}
public class Employee extends Person{
...
}
public class Main {
    public static void main(String[] args) {
        PersonenGenerator pg = new PersonenGenerator();
        pg.Student s1 = new Student(...);
        pg.personSet.add(s1);
        pg.Employee e1 = new Employee(...);
        pg.personSet.add(e1);


        printPersonTypeSet(Employee) //pass Employee as parameter SOMEHOW
    }
}

预期行为(输出):

  

员工{value1,value2,value3}

由于某种原因,我的编译器不喜欢if语句。特别是我打电话给clazz

ACTUAL BEHAVIOR(编译器错误):

  

未知类:&#39; clazz&#39;

我的问题是我打算将clazz用作Person实例的变量,而Person是各种子类的超类。

如何保留预期的功能并满足我的编译器? 第一次这样做。

编辑:我觉得自己被误解了。我想传递一个类作为检查条件的参数。我评论了代码以澄清这一点。

如果将参数作为类型Class传递是废话,那么就这样说。这是一个想法,因为我不知道如何传递一个类作为参数。

3 个答案:

答案 0 :(得分:2)

你想要clazz.isAssignableFrom(instance.getClass())。如果true的类型为instance,或者类型为clazz的子类型,则会返回clazz

编辑:这是一个更完整的例子。你有一个Person类和一些子类:

class Person {
    String name;
    Person(String n) { name = n; }
    public String toString() { return name; }
}

class GoodPerson extends Person {
    GoodPerson(String n) {
        super(n);
    }
}

class BadPerson extends Person {
    BadPerson(String n) {
        super(n);
    }
}

然后您将代码用于我建议的编辑:

public void printPersonTypeSet(Class<?> clazz) {
    for (Person instance : personSet)
        if (clazz.isAssignableFrom(instance.getClass()))
            System.out.println(instance);
}

如果personSet初始化为:

Set<Person> personSet = new HashSet<Person>();
personSet.add(new GoodPerson("Good1"));
personSet.add(new GoodPerson("Good2"));
personSet.add(new BadPerson("Bad1"));

然后您可以使用GoodPerson找到printPersonTypeSet(GoodPerson.class)的实例。 (注意,这也会找到GoodPerson的子类。)

答案 1 :(得分:1)

在您的示例中,clazzClass的一个实例,这可能不是您希望在方法中作为参数提供的内容。所以你问你的编译器instanceclazz的实例,它不能是clazz不是类而是实例。

答案 2 :(得分:1)

最好的方法是使用isInstance(Class)方法。根据Java文档,此方法是Java语言instanceof运算符的动态等价物。

public void printPersonTypeSet(Class clazz){
    Set<Person> personSet = ImmutableSet.of(new Person());
    for(Person instance : personSet){
        if (clazz.isInstance(instance.getClass())) System.out.println(instance);
    }
}
public static void main(String[] args) {
    new Scratch().printPersonTypeSet(Person.class);
}

来自Java doc:

  

确定指定的{@code Object}是否与赋值兼容   使用此{@code Class}表示的对象。这个方法是   Java语言的动态等价物{@code instanceof}   运营商。如果指定,则该方法返回{@code true}   {@code Object}参数为非null并且可以强制转换为   此{@code Class}对象表示的引用类型没有   提出{@code ClassCastException。}它返回{@code false}   否则。

方法签名

public native boolean isInstance(Object obj)