如何使用可克隆类型作为Java泛型类的参数

如何使用可克隆类型作为Java泛型类的参数,java,generics,cloneable,Java,Generics,Cloneable,我有一个泛型类,需要能够克隆参数类型的对象。下面是一个非常简单的例子。编译器声明类型对象中的clone()不可见 public class GenericTest<T extends Cloneable> { T obj; GenericTest(T t) { obj = t; } T getClone() { // "The method clone() from the

我有一个泛型类,需要能够克隆参数类型的对象。下面是一个非常简单的例子。编译器声明类型对象中的clone()不可见

public class GenericTest<T extends Cloneable>
    {
    T obj;
    GenericTest(T t)
        {
        obj = t;
        }
    T getClone()
        {
        // "The method clone() from the type Object is not visible."
        return (T) obj.clone();
        }
    }
公共类泛型测试
{
T-obj;
一般测试(T)
{
obj=t;
}
T getClone()
{
//“类型对象中的方法clone()不可见。”
返回(T)obj.clone();
}
}
我不希望调用方进行克隆,因为要保持对象的完整性,还需要做其他事情。上面的代码只是问题的一个例子,没有我必须维护的与克隆对象相关的其他数据的干扰


有没有办法绕过这个问题,或者这是java设计者认为合理化其缺点的一个例子,等同于没有一个?

< p>因为在对象< /C>类中,该方法被标记为“代码>保护< /代码>,因此一般不能将该方法称为任意对象。我个人一开始并不认为这是个问题(嘿,我是
对象
的子类,所以我应该能够调用其受保护的方法,对吧?),但是编译器需要知道你是目标对象类(或其包)的子类,才能调用受保护的方法,这两种方法在这里都不适用

clone()
方法背后的思想是,支持它的类将重写该方法,并将其声明为
public

这里唯一保留完整功能的真正解决方案是使用反射来访问方法并绕过访问修饰符。另一种方法是编写自己的
MyCloneable
接口,该接口上声明了一个public
clone()
方法;如果您只传入自己的域类,这可能会起作用,但这意味着您无法在外部类(如
java.util.String
java.util.ArrayList
)上使用它,因为您无法强制它们实现您的接口


根据对的回答,这是一个非常可疑的设计。

Java方面的一个错误。反思是正确的选择

static Method clone = Object.class.getMethod("clone"); 

static public <T extends Cloneable> 
T clone(T obj)
    return (T) clone.invoke(obj);
静态方法clone=Object.class.getMethod(“clone”);
静态公众
T克隆(T obj)
return(T)clone.invoke(obj);

我需要克隆一个包含字段的POJO。工作内容如下:

public static Object clone(Object o)
{
  Object clone = null;

  try
  {
     clone = o.getClass().newInstance();
  }
  catch (InstantiationException e)
  {
     e.printStackTrace();
  }
  catch (IllegalAccessException e)
  {
     e.printStackTrace();
  }

  // Walk up the superclass hierarchy
  for (Class obj = o.getClass();
    !obj.equals(Object.class);
    obj = obj.getSuperclass())
  {
    Field[] fields = obj.getDeclaredFields();
    for (int i = 0; i < fields.length; i++)
    {
      fields[i].setAccessible(true);
      try
      {
        // for each class/suerclass, copy all fields
        // from this object to the clone
        fields[i].set(clone, fields[i].get(o));
      }
      catch (IllegalArgumentException e){}
      catch (IllegalAccessException e){}
    }
  }
  return clone;
}
公共静态对象克隆(对象o)
{
对象克隆=空;
尝试
{
clone=o.getClass().newInstance();
}
捕获(实例化异常e)
{
e、 printStackTrace();
}
捕获(非法访问例外e)
{
e、 printStackTrace();
}
//向上走超类层次结构
对于(类obj=o.getClass();
!obj.equals(Object.class);
obj=obj.getSuperclass())
{
Field[]fields=obj.getDeclaredFields();
for(int i=0;i
Craig-我不认为泛型导致了您的问题,这或多或少是因为
Object.clone()
受到了保护。有关更多上下文,请参阅。是否在传递的类T上实现克隆?Cloneable是在Object中实现的,但要正常工作,它还必须在您使用的每个派生类上实现。。。这只是一个对对象中的实现说“请不要抛出异常”的标记接口。@newacct这是一个错误:阅读@newacct上的注释我链接到该错误的原因是因为Java实现者Joshua Bloch和Ken Arnold(尽管他们不一定是Cloneable的原始设计者)指出当前可克隆接口“实际上毫无用处”,如果不是不兼容的更改,他们会添加公共克隆方法,尽管我进一步思考后意识到,由于他们可能不是最初的可克隆设计师,这并不意味着错误的一个公开的例子。@ NeXACT我解释了不知名的“java部分的错误”,这表明它是java编程语言设计中的一个错误,我认为不做<代码>克隆()。Cloneable的成员是一个语言设计错误。@newact事实上,
Cloneable
没有被定义为“具有克隆方法的类型”是设计错误(IMO),因为如果被定义为这样的话,它会更直观、更有用。