Java - 在方法参数中使用Class参数

时间:2017-10-19 12:15:15

标签: java generics java-7

我有以下课程:

public class Publisher<T> {

    private static final Class[] SUPPORTED_CLASSES = new Class[]{T1.class, T2.class};

    public Publisher() {
        if(Arrays.asList(SUPPORTED_CLASSES).contains(T)) { // error: expression expected!
            System.out.println("Class not supported!");
        }
    }
}

如何检查类参数是否符合实现?
在上面的例子中,我不能使用类参数T作为参数。

3 个答案:

答案 0 :(得分:13)

为什么这不起作用

您正试图在运行时访问泛型类型,由于type erasure,在这种情况下不起作用。

如何修复

解决这个问题的最简单方法是在构造函数中使用Class<T>,它会在运行时为您提供类型,然后您可以检查List是否包含您已经给出的值。

示例代码

public Publisher(Class<T> clazz) {
    if(!SUPPORTED_CLASSES.contains(clazz)) {
        System.out.println("Class not supported!");
    }
}

可能出现的问题

您的代码目前不支持子类型,这可能会导致问题,除非您对此有所帮助(您可以使用列表,但不一定是ArrayLists),但这确实会导致LSP

答案 1 :(得分:6)

虽然其他一些答案非常好,但我想提出另一个解决方法:

您可以创建一个空接口<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_gravity="center" android:layout_weight="100" android:gravity="center_horizontal" android:orientation="horizontal"> <EditText android:id="@+id/txtMinutes" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00000000" android:gravity="center_vertical" android:hint="00" android:inputType="number" android:maxLength="2" android:singleLine="true" android:textColor="#2f8677" android:textColorHint="#2f8677" android:textSize="40sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:layout_gravity="top" android:gravity="center_vertical" android:text=":" android:textColor="#2f8677" android:textSize="40dp" /> <EditText android:id="@+id/txtSeconds" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00000000" android:gravity="center_vertical" android:hint="00" android:inputType="number" android:maxLength="2" android:singleLine="true" android:textColor="#2f8677" android:textColorHint="#2f8677" android:textSize="40sp" /> <TextView android:layout_width="wrap_content" android:layout_height="wrap_content" android:gravity="center_vertical" android:text=":" android:textColor="#2f8677" android:textSize="40dp" /> <EditText android:id="@+id/txtTimerMicroSeconds" android:layout_width="wrap_content" android:layout_height="wrap_content" android:background="#00000000" android:gravity="center_vertical" android:hint="00" android:inputType="number" android:maxLength="2" android:singleLine="true" android:textColor="#2f8677" android:textColorHint="#2f8677" android:textSize="40sp" /> </LinearLayout> ,并让列表中的所有类都实现此接口。然后,您可以将类声明更改为:

MyInterface

这将达到你的目的。

答案 2 :(得分:4)

您需要将类传递给构造函数:

public Publisher(Class<T> clazz) {
    if(!SUPPORTED_CLASSES.contains(clazz)) {
        System.out.println("Class not supported!");
    }
}

因为T在运行时不可用:将为new Publisher<T1>()new Publisher<T3>()执行完全相同的代码。