为什么这仍然需要在 java 中投射?
why is this still need to cast in java?
错误
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return new DefaultLiteProcessScope();
}
}
对
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return (S) new DefaultLiteProcessScope();
}
}
DefaultLiteProcessScope 扩展了 DefaultLiteProcessScope,但直到需要强制转换?为什么?
S
扩展了 DefaultLiteProcessScope
,因此您正在尝试 return 父 class 实例而不是子 class 实例。
原因是代码错误
public class MyOtherFactory<SubclassOfDefaultLiteProcessScope> {}
会中断,因为 DefaultLiteProcessScope 不是 SubclassOfDefaultLiteProcessScope。
您的代码会在以下实例中抛出 ClassCastException
:
class CustomLiteProcessScope extends DefaultLiteProcessScope { ... }
final DefaultLiteProcessScopeFactory<CustomLiteProcessScope> factory = new ...;
然后:
factory.build(); <-- Exception trying to cast DefaultLiteProcessScope to CustomLiteProcessScope
你在这里做的是错误的。您想要从 build
方法中 return DefaultLiteProcessScope
的某些子类型。但是,您可以像这样硬编码 return 类型:new DefaultLiteProcessScope()
。现在想像这样一个稍微做作的例子。
static class SubType extends DefaultLiteProcessScope {
}
然后是客户端代码。
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build();
现在,由于您有 hard-coded return 类型,您的编译器无法保证代码的类型安全。我希望它是 return 子类型,但是你有 hard-coded 而不是 super-type。因此,它会要求您添加显式强制转换,这很公平,不是吗?事实上,此转换在运行时失败并抛出 java.lang.ClassCastException
,因为超类型 DefaultLiteProcessScope
无法转换为子类型 SubType
.
如何修复。
更好的方法是像这样将供应商作为参数传递给您的构建方法。
static class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build(Supplier<S> s) {
return s.get();
}
}
static interface LiteProcessScopeFactory<S> {
S build(Supplier<S> s);
}
这是新的客户端代码。
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build(SubType::new);
错误
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return new DefaultLiteProcessScope();
}
}
对
public class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build() {
return (S) new DefaultLiteProcessScope();
}
}
DefaultLiteProcessScope 扩展了 DefaultLiteProcessScope,但直到需要强制转换?为什么?
S
扩展了 DefaultLiteProcessScope
,因此您正在尝试 return 父 class 实例而不是子 class 实例。
原因是代码错误
public class MyOtherFactory<SubclassOfDefaultLiteProcessScope> {}
会中断,因为 DefaultLiteProcessScope 不是 SubclassOfDefaultLiteProcessScope。
您的代码会在以下实例中抛出 ClassCastException
:
class CustomLiteProcessScope extends DefaultLiteProcessScope { ... }
final DefaultLiteProcessScopeFactory<CustomLiteProcessScope> factory = new ...;
然后:
factory.build(); <-- Exception trying to cast DefaultLiteProcessScope to CustomLiteProcessScope
你在这里做的是错误的。您想要从 build
方法中 return DefaultLiteProcessScope
的某些子类型。但是,您可以像这样硬编码 return 类型:new DefaultLiteProcessScope()
。现在想像这样一个稍微做作的例子。
static class SubType extends DefaultLiteProcessScope {
}
然后是客户端代码。
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build();
现在,由于您有 hard-coded return 类型,您的编译器无法保证代码的类型安全。我希望它是 return 子类型,但是你有 hard-coded 而不是 super-type。因此,它会要求您添加显式强制转换,这很公平,不是吗?事实上,此转换在运行时失败并抛出 java.lang.ClassCastException
,因为超类型 DefaultLiteProcessScope
无法转换为子类型 SubType
.
如何修复。
更好的方法是像这样将供应商作为参数传递给您的构建方法。
static class DefaultLiteProcessScopeFactory<S extends DefaultLiteProcessScope> implements LiteProcessScopeFactory<S> {
@Override
public S build(Supplier<S> s) {
return s.get();
}
}
static interface LiteProcessScopeFactory<S> {
S build(Supplier<S> s);
}
这是新的客户端代码。
final LiteProcessScopeFactory<SubType> f = new DefaultLiteProcessScopeFactory<>();
final SubType result = f.build(SubType::new);