泛型类实现clone()遇未检查转换与访问权限问题求解
泛型Cloneable类的clone()方法正确实现方案
修正后的完整代码
import java.lang.reflect.Method; public class GenericNode<E extends Cloneable> implements Cloneable { private E value; private GenericNode<E> north, south, west, east; @Override @SuppressWarnings("unchecked") public GenericNode<E> clone() throws CloneNotSupportedException { // 处理未检查转换警告 GenericNode<E> copiedNode = (GenericNode<E>) super.clone(); // 处理value的clone访问权限问题 if (this.value != null) { try { Method cloneMethod = this.value.getClass().getMethod("clone"); copiedNode.value = (E) cloneMethod.invoke(this.value); } catch (Exception e) { throw new CloneNotSupportedException("无法克隆类型为" + this.value.getClass().getName() + "的value"); } } // 若需要克隆north/south/west/east节点,可在此处添加对应clone逻辑(默认是浅拷贝) // copiedNode.north = this.north.clone(); return copiedNode; } }
问题1:未检查转换警告的解决
Java泛型擦除后,super.clone()返回Object,强制转GenericNode<E>会触发未检查转换警告。这里有两种稳妥的处理方式:
- 注解抑制(推荐):直接在
clone()方法上添加@SuppressWarnings("unchecked")。因为遵循Cloneable规范的类,super.clone()必然返回当前类的实例,这个警告是安全的。 - 类型校验(可选):先校验返回对象的类型再转换,避免类型转换错误:
Object clonedObj = super.clone(); if (!(clonedObj instanceof GenericNode)) { throw new CloneNotSupportedException("克隆得到的对象类型不符合预期"); } GenericNode<E> copiedNode = (GenericNode<E>) clonedObj;
问题2:泛型E的clone()访问权限问题
Object的clone()是protected方法,即便E extends Cloneable,也无法直接调用this.value.clone()(除非E显式重写了public的clone方法,但泛型约束无法保证这一点)。只能通过反射绕开权限限制:
- 通过
getClass().getMethod("clone")获取E类的public clone方法(符合Cloneable规范的类都应该提供这个方法)。 - 调用
invoke(this.value)执行克隆,再强制转换为E类型。 - 将反射过程中出现的异常统一转换为
CloneNotSupportedException抛出,符合方法声明的异常类型。
内容的提问来源于stack exchange,提问作者Saiko
相关产品推荐
相关产品推荐

