当前位置: 首页 > 面试题库 >

为什么将泛型的类强制转换为Class 不安全吗?

班建义
2023-03-14
问题内容

我正在制作一个MethodPointer类,以便模拟C ++中的函数指针的功能。最初,我只用Objects 做所有事情,但后来我有了一个想法-
为什么不使其真正通用?

问题出在这个构造函数上,该构造函数试图使用签名调用另一个构造函数MethodPointer(Class<T> clazz, String methodName, Class<?> ... paramClasses)

public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
    this(object.getClass(), methodName, paramClasses);
    this.object = object;
}

我以为这会很好,但是我收到了以下编译器错误:

The constructor MethodPointer<T>(Class<capture#1-of ? extends Object>,
String, Class<?>[]) is undefined

因此,我很困惑,我这样做:

public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
    this((Class<T>) object.getClass(), methodName, paramClasses);
    this.object = object;
}

现在可以编译,但是我收到以下警告:

Unchecked cast from Class<capture#1-of ? extends Object> to Class<T>

我想问题是我不明白这Class<capture#1-of ? extends Object>意味着什么。我认为,由于TT object参数推断出的类型,因此有 必要 调用object.getClass()返回一个Classtype
的对象Class<T>。显然,事实并非如此。有人可以消除我的困惑吗?

完整的类声明和所有构造函数:

public class MethodPointer<T> {

    //Logger instance
    private static final Logger LOGGER = Logger.getLogger(MethodPointer.class);

    //Object fields
    private final Method method;
    private ArrayList<Object> args = new ArrayList<Object>();
    private T object = null;


    //Constructors
    public MethodPointer(Method method) {
        this.method = method;
    }

    public MethodPointer(Class<T> clazz, String methodName, Class<?> ... paramClasses) {
        Method theMethod = null;
        try {
            theMethod = clazz.getMethod(methodName, paramClasses);
        }
        catch(NoSuchMethodException nsme) {
            LogUtil.log(LOGGER, Level.ERROR, "Unable to find method " + methodName + " in " + clazz.getSimpleName(), nsme);
        }
        method = theMethod;
    }

    public MethodPointer(T object, String methodName, Class<?> ... paramClasses) {
        this((Class<T>) object.getClass(), methodName, paramClasses);
        this.object = object;
    }

问题答案:

SLaks的答案指出object.getClass()衰减到Class<? extends Object>,以解释编译错误。但它 并不安全
投来Class<T>

getClass“返回运行时类”被调用的对象。例如,如果我们内部MethodPointer<Number>,则object
是-A
Number,但其运行时类型可能IntegerDouble等等。这告诉我们,铸造object.getClass()Class<T>是不是安全的,因为Class<Integer>Class<Number>是不同的对象,代表不同阶级-
这似乎非常相关的一个区别正确性的尝试。

那么解决方案是什么?好吧,不要投。坚持Class<T>从呼叫者那里接一个。



 类似资料:
  • 此代码有效。它以“未检查或不安全操作”警告进行编译和运行。 当这两个给我运行时错误时 我遇到的错误如下:

  • 我有一个通用类。它看起来像这样: 显然,conevertdatajsonstring方法仅在字符串类型为T时调用。但有一个警告: 类型安全:未选中从字符串转换为T 有没有一种方法可以在不使用SuppressWarnings的情况下解决此问题: @抑制警告(“未选中”) 方法之前?

  • 我有一个父类来处理我所有的自定义异常,父母异常。我希望所有的子异常都有一个方法来向异常添加消息。为了做到这一点,我创建了一个泛型方法,在向其添加消息后返回泛型类型的对象。我在父类方法中使用来添加消息,然后返回,但是由于该方法返回泛型类型,所以我将其转换为泛型类型T。这似乎是可行的,但是给出了警告。我的代码如下: 该行给出的警告是。这种方法似乎确实如预期的那样有效,所以我并不担心,但我想更好地理解为

  • 有没有一种简单的方法可以做到这一点: 编辑:我写了一份正确答案的工作副本:

  • 问题内容: 有人可以向我解释为什么以下代码示例中标记的行不起作用吗? 具体来说,当我们说类型为时,这并不表示它的每个元素都是的实例吗?如果是这样,那么它是什么铸造的问题,如果我们都可以投射单个实例来? 谢谢。 问题答案: 问题是这样的: 如果对数组执行相同的操作,则在运行时会在第4行获得ArrayStoreException。对于泛型集合,已决定在编译时避免这种情况。

  • 问题内容: 执行此强制转换时出现编译错误: 应该被继承,尽管不能直接继承。 从文档: 农具其中inturn & 为什么这无效? 也感谢您提供有关使用as 的正确方法的意见? 我正在考虑包装方法。 问题答案: 扩展,并且 不 扩展。 如果您想从中获得帮助,我认为实现包装器类是您最简单的选择。幸运的是的唯一抽象方法是。 RandomAccessFile实现了DataInput,该数据输入将依次转为Da