繁体   English   中英

如何将Cloneable类型用作Java泛型类的参数

[英]How to use Cloneable type as parameter to Java generic class

我有一个通用类,需要能够克隆参数类型的对象。 下面是一个非常简单的例子。 编译器声称来自Object类型的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();
        }
    }

我宁愿不让调用者进行克隆,因为还有其他事情必须发生以维护对象的完整性。 上面的代码只是问题的一个例子,没有我必须维护的与克隆对象相关的其他数据的噪音。

有没有办法绕过这个或者这是Java设计师考虑合理化其缺点的另一个例子,相当于没有?

因为该方法在Object类上标记为protected ,所以通常不能在任意对象上调用此方法。 我个人认为这不会是一个问题(嘿,我是Object的子类,所以我应该能够调用它的受保护方法,对吧?),但编译器需要知道你是一个目标对象的类(或其包)中的子类,以便调用受保护的方法,这两种方法都不适用于此处。

clone()方法背后的想法是支持它的类将覆盖该方法,将其声明为public

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

根据相关问题的答案,这是一个非常可疑的设计。

Java的一个错误。 反思是正确的方法

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

static public <T extends Cloneable> 
T clone(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;
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM