gpt4 book ai didi

Java:反射、通用类型和未检查的转换

转载 作者:塔克拉玛干 更新时间:2023-11-02 08:41:32 59 4
gpt4 key购买 nike

我的类(class)将获得一个 Object 类(class)。然后我使用反射遍历该类的声明字段并注册一个 ChangeListener在每个字段上使用 Property基类。

原始的“createChangeListener”方法如下所示:

private void createChangeListener(Property property) {
property.addListener(new ChangeListener() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
Foo.this.propertyChanged(observable);
}
});
}

但是,这会产生不需要的警告:

warning: [unchecked] unchecked call to addListener(ChangeListener<? super T>) as a member of the raw type ObservableValue
property.addListener(new ChangeListener() {
where T is a type-variable:
T extends Object declared in interface ObservableValue

不要被劝阻,我为我的 Property 提供了一个通用类型参数和 ChangeListener :

private void createChangeListener(Property<Object> property) {
property.addListener(new ChangeListener<Object>() {
@Override
public void changed(ObservableValue observable, Object oldValue, Object newValue) {
Foo.this.propertyChanged(observable);
}
});
}

...直到现在才被告知我只是将我的问题转移到反射源。下面的代码现在修改为转换为 Property<Object>从原来的Property没有通用类型:

if (Property.class.isAssignableFrom(field.getType())) {
createChangeListener((Property<Object>)(field.get(model)));
}

这个以前没有警告的代码现在正在产生头部倾斜:

warning: [unchecked] unchecked cast
createChangeListener((Property<Object>)(field.get(model)));
required: Property<Object>
found: Object

问题:

  • ಠ_ಠ
  • 鉴于 Java 的类型删除限制,我可以使用哪些技术来安全地解决这些警告?
  • 在原始的非类型化方法中抑制未经检查的警告是否安全?

最佳答案

将您的字段值转换为 Property<Object>你明确地说 Property通用参数是 Object ,这可能是错误的,编译器无法帮助您。比如字段的真实类型是Property<String>您可以执行以下操作:

Property<Object> p = (Property<Object>)(field.get(model)); // compiler warning, runtime ok
p.setValue(new Object()); // runtime ok, but now you're probably stored incompatible value

// somewhere much later in completely different piece of code
String value = this.propertyField.getValue(); // sudden ClassCastException

因此编译器会警告您转换为 Property<Object>你在做一个编译器无法证明的假设,并且你实际上可能有不同的类型,这可能导致将对象置于不正确的状态,这可能会在以后的某个地方破坏你的程序。

在您的特定情况下,您不想说“我知道通用参数类型是 Object”。你想说的是“我不关心泛型参数类型”。对于这种情况,有一个特殊的结构 <?> .你可以在这里使用它:

void createChangeListener(Property<?> property) {
property.addListener(new ChangeListener<Object>() {
@Override
public void changed(ObservableValue<?> observable,
Object oldValue, Object newValue) {
Foo.this.propertyChanged(observable);
}
});
}

并且您可以安全地转换为 Property<?>没有任何警告。但是现在你不能调用 setValue根本不需要,但似乎您根本不​​需要。

关于Java:反射、通用类型和未检查的转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32857360/

59 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com