泛型未经检查的转换警告
Unchecked conversion warning with generics
我不太明白,为什么我的代码必须进行未经检查的转换以及如何解决这个问题。
我正在使用构建器模式实现不可变对象,为此我使用内部接口 "Builder".
实现了 "Immutable" 接口
每个不可变 class 实现 Immutable 接口并实现内部静态 class Builder,后者实现 Builder 接口。
一切正常。
现在,我正在实现一堆非常简单的 classes,它们并不真正需要构建器,但我仍然想实现 Immutable 接口,所以那些 class 的对象es 是 "Immutable" 的实例,但我不想为每个 class 实现没有任何功能的空构建器。我宁愿有一个抽象的 class,在其中为所有简单的 classes 实现一个简单的构建器。 builder 只会存储原始对象,return 通过 build() 方法将其存储,因此完全实现了 Immutable 接口
构建器的 build() 方法必须 return 实现 class 的对象。所以我添加了泛型。
public interface Immutable {
public interface Builder<T> {
public T build();
}
public <T> Builder<T> builder();
}
public interface Interface extends Immutable {
public interface BuilderInterface<T> extends Immutable.Builder<T> {
}
}
public abstract class AbstractClass implements Interface {
public static class AbstractBuilder<T> implements Interface.BuilderInterface<T> {
private final T object;
public AbstractBuilder(T object) {
this.object = object;
}
@Override
public T build() {
return this.object;
}
}
protected AbstractClass() {
super();
}
}
public class ConcreteClass extends AbstractClass {
public ConcreteClass() {
}
@Override
public AbstractBuilder<ConcreteClass> builder() {
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
}
}
我原以为 Immutable 接口的通用类型 T 会采用实现的类型 class,但它似乎是 Object,这会导致以下警告:
类型安全:来自类型 ConcreteClass 的 builder() 的 return 类型 AbstractClass.AbstractBuilder 需要未经检查的转换以符合来自类型 Immutable
的 Immutable.Builder
编辑: ConcreteClass 的 builder() 方法发出警告。
这很简单 - Immutable#builder
的方法签名需要类型参数 T
为实际方法调用设置 "on the fly" 而不是绑定到 class。要适当地覆盖此方法,ConcreteClass
中的签名将是
public <T> Builder<T> builder() {
这显然与您的构建器定义冲突
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
为了使这一切都可编译,您必须从 class 而不是从方法调用者推断 T
for Immutable#builder
,即您最终拥有
public interface Immutable<T> {
public interface Builder<T> {
public T build();
}
public Builder<T> builder();
}
并且所有继承的 classes 相应地改变以将 T
传递给它的前辈。
public interface Interface<T> extends Immutable<T> {
public interface BuilderInterface<T> extends Immutable.Builder<T> {
}
}
public abstract class AbstractClass<T> implements Interface<T> {
public static class AbstractBuilder<T> implements Interface.BuilderInterface<T> {
private final T object;
public AbstractBuilder(T object) {
this.object = object;
}
@Override
public T build() {
return this.object;
}
}
protected AbstractClass() {
super();
}
}
public class ConcreteClass extends AbstractClass<ConcreteClass> {
public ConcreteClass() {
}
@Override
public Builder<ConcreteClass> builder() {
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
}
}
我不太明白,为什么我的代码必须进行未经检查的转换以及如何解决这个问题。
我正在使用构建器模式实现不可变对象,为此我使用内部接口 "Builder".
实现了 "Immutable" 接口每个不可变 class 实现 Immutable 接口并实现内部静态 class Builder,后者实现 Builder 接口。
一切正常。
现在,我正在实现一堆非常简单的 classes,它们并不真正需要构建器,但我仍然想实现 Immutable 接口,所以那些 class 的对象es 是 "Immutable" 的实例,但我不想为每个 class 实现没有任何功能的空构建器。我宁愿有一个抽象的 class,在其中为所有简单的 classes 实现一个简单的构建器。 builder 只会存储原始对象,return 通过 build() 方法将其存储,因此完全实现了 Immutable 接口
构建器的 build() 方法必须 return 实现 class 的对象。所以我添加了泛型。
public interface Immutable {
public interface Builder<T> {
public T build();
}
public <T> Builder<T> builder();
}
public interface Interface extends Immutable {
public interface BuilderInterface<T> extends Immutable.Builder<T> {
}
}
public abstract class AbstractClass implements Interface {
public static class AbstractBuilder<T> implements Interface.BuilderInterface<T> {
private final T object;
public AbstractBuilder(T object) {
this.object = object;
}
@Override
public T build() {
return this.object;
}
}
protected AbstractClass() {
super();
}
}
public class ConcreteClass extends AbstractClass {
public ConcreteClass() {
}
@Override
public AbstractBuilder<ConcreteClass> builder() {
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
}
}
我原以为 Immutable 接口的通用类型 T 会采用实现的类型 class,但它似乎是 Object,这会导致以下警告:
类型安全:来自类型 ConcreteClass 的 builder() 的 return 类型 AbstractClass.AbstractBuilder 需要未经检查的转换以符合来自类型 Immutable
的 Immutable.Builder编辑: ConcreteClass 的 builder() 方法发出警告。
这很简单 - Immutable#builder
的方法签名需要类型参数 T
为实际方法调用设置 "on the fly" 而不是绑定到 class。要适当地覆盖此方法,ConcreteClass
中的签名将是
public <T> Builder<T> builder() {
这显然与您的构建器定义冲突
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
为了使这一切都可编译,您必须从 class 而不是从方法调用者推断 T
for Immutable#builder
,即您最终拥有
public interface Immutable<T> {
public interface Builder<T> {
public T build();
}
public Builder<T> builder();
}
并且所有继承的 classes 相应地改变以将 T
传递给它的前辈。
public interface Interface<T> extends Immutable<T> {
public interface BuilderInterface<T> extends Immutable.Builder<T> {
}
}
public abstract class AbstractClass<T> implements Interface<T> {
public static class AbstractBuilder<T> implements Interface.BuilderInterface<T> {
private final T object;
public AbstractBuilder(T object) {
this.object = object;
}
@Override
public T build() {
return this.object;
}
}
protected AbstractClass() {
super();
}
}
public class ConcreteClass extends AbstractClass<ConcreteClass> {
public ConcreteClass() {
}
@Override
public Builder<ConcreteClass> builder() {
return new AbstractClass.AbstractBuilder<ConcreteClass>(this);
}
}