java中如何取到一个对象的所有属性值,并且在创建一个相同的对象

:cry:

对象的类不知道,里面属性的类型也不知道。我感觉我没救了

正常来说针对复制对象就只有这三种方式了.
1.clone (需要实现Cloneable接口)
2.序列化反序列化(需要实现Serializable接口,就是上面的流方式)
3.构造新对象,通过反射取值,填充值(我给出的办法)

再就是可能一些字节码修改工具包可能会有效.不过需要引入额外的Jar包.比较复杂了.

都有对象了,为什么不知道对象的类呢?

用反射机制吧,很轻松!

对呀,用反射。
反射可以从一个类的绝对名生成对象,例如“com.java.Sun”的串,可以实例化Sun对象,也可以执行对象中的方法。

object.getClass().getFields();可以得到对象属性。object是某对象的实例。类似的可以得其方法和名称。得到名称了也就又可以按这个名称实例化对象喽。

a.getClass().getDeclaredFields()

[code="java"] public static Object deepClone(Object obj) {
try {
ByteArrayOutputStream bo = new ByteArrayOutputStream();
ObjectOutputStream oo = new ObjectOutputStream(bo);
oo.writeObject(obj);
// 从流里读回来
ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
ObjectInputStream oi = new ObjectInputStream(bi);
return (oi.readObject());
}
catch(Exception e) {
}
return obj;
}[/code]

感觉你是不是处理问题的方法不对。会出现这种情况,或是设计不当。补充说明,那个被克隆的对象,必须implements Serializable 接口。是对原来对象的克隆,属性值都是一样的,但hashcode不一样,它是新的对象了。

新手.....虽然昨天我也是..... :cry:
这段代码你可以执行一下试试.
[code="java"]import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import sun.misc.Unsafe;
public class TestClass {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) throws Exception {

    TestClass tc = new TestClass();
    tc.setName("oUCHxP");
    //现在是一个未知类型的对象(模拟一下)
    Object obj = tc;

    //获取对象类型,可以看到输出是TestClass类型
    Class c = obj.getClass();
    System.out.println(c);

    //创建此类型的空对象
    Field fu = Unsafe.class.getDeclaredField("theUnsafe");
    fu.setAccessible(true);
    Unsafe us = (Unsafe) fu.get(null);
    Object newObj = us.allocateInstance(c);

    //可以看到name是空的
    System.out.println("newObj.name: " + ((TestClass) newObj).getName());

    //获取所有成员(包括private)的值,并拷贝到新对象中
    Field[] fields = c.getDeclaredFields();
    for (Field f : fields) {
        //不拷贝static成员和final成员
        if (Modifier.isStatic(f.getModifiers()) || Modifier.isFinal(f.getModifiers())) {
            continue;
        }
        f.setAccessible(true);
        Object fieldValue = f.get(obj);
        f.set(newObj, fieldValue);
    }

    //再看一下新对象里的内容,private成员也被复制过来了
    System.out.println("newObj.name: " + ((TestClass) newObj).getName());
}

}[/code]

这个用反射有点浪费了。。不知道这样能不能解决这个兄弟的问题[code="java"]package com.zhy.test.prototype;
public class TestClone {

/** 原型模式 
 * @param args  
 */  

public static void main(String[] args) {   
    try {   
        new TestClone().cloneObject();   
    } catch (CloneNotSupportedException e) {   
        e.printStackTrace();   
    }   
}   

public void cloneObject() throws CloneNotSupportedException {   
    Person p = new Person();   
    Man man = new Man();   
    man.setSalory("111123");   
    p.setName("zhangfei");   
    p.setMan(man);   
    //man.setSalory("122335");//(1)   
    Person pp = p.getClonePerson(p);   
    man.setSalory("122335");//(2)   
    pp.setName("aa");   
    System.out.println("pp.getName()= " + pp.getName() + " pp.man.getSalory()= "+pp.getMan().getSalory());   
    System.out.println("p.getName()=" + p.getName()+" p.man.getSalory()= "+p.getMan().getSalory());   
}   

}

class Person implements Cloneable {

private String name = "";

private Man man;

public String getName() {   
    return name;   
}   

public void setName(String name) {   
    this.name = name;   
}   


public Person getClonePerson(Person p) throws CloneNotSupportedException {   
    Person pp = (Person) p.clone();   
    return pp;   
}   

public Man getMan() {   
    return man;   
}   

public void setMan(Man man) {   
    this.man = man;   
}   

public Object clone() throws CloneNotSupportedException{   
    Person p = (Person) super.clone();   
    p.man = this.getMan().getCloneMan(this.getMan());   
    return p;   
}   

}

class Man implements Cloneable{

private String salory = "";

public String getSalory() {   
    return salory;   
}   

public void setSalory(String salory) {   
    this.salory = salory;   
}    
public Man getCloneMan(Man man) throws CloneNotSupportedException{   
    Man ma = (Man)man.clone();   
    return ma;   
}   

}

[/code]

[quote="zhanghaiyangruijie"]这个用反射有点浪费了。。不知道这样能不能解决这个兄弟的问题..[/quote]
[quote="lz"]对象的类不知道,里面属性的类型也不知道。[/quote]
未必实现了Cloneable接口

一定不用反射么,用反射很容易实现的
[code="java"]
public static void main(String[] args) throws Exception {
//假设我们不知道这个对象是什么,所以用object引用,为了省事,就不写po类了,直接用了java.util.Date
Object o = new Date();
Object o2 = o.getClass().newInstance();
//遍历所有成员变量
for(Field f : o.getClass().getDeclaredFields()) {
//如果是final成员就跳过
if(Modifier.isFinal(f.getModifiers()))continue;
//设置成员变量访问权
f.setAccessible(true);
//设置成员变量内容
f.set(o2, f.get(o));
}
System.out.println(o.equals(o2));
}
[/code]
程序运行结果为true

LS的有BUG哦 :D
newInstance()调用了构造器.
构造器中可能有对final成员的初始化,而拷贝时跳过了final成员.
所以拷贝前后的两个final变量有可能值不同哦.(比如说用时间初始化)
所以拷贝时应该跳过static成员,而不应该跳过final成员.

PS:我上面给的代码也有问题.跳过条件应该只用Modifier.isStatic(f.getModifiers())