今天才知道传参如果是传的是对象的话,是引用传递,不是值传递,所以父类的值可能被修改,这样就不安全了。。。。
度娘说的把对象复制一下再传过去。。。
度娘还是复制方法已经知道两了,克隆和序列化
克隆:
Bean
package zzg;
public class Bean implements Cloneable{
private String name;
private String pass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
/**
*
* @Title: setPass
* @Description: TODO(对象clone,必须实现了Cloneable接口,如果复制改A类中的对象C,需要再次函数中调用C的Clone方法(C也得写CLone方法))
* @param pass void
* @throws
* 注:
* 有三个值得注意的地方,一是希望能实现clone功能的CloneClass类实现了Cloneable接口,这个接口属于java.lang包,java.lang包已经被缺省的导入类中,
* 所以不需要写成java.lang.Cloneable。另一个值得请注意的是重载了clone()方法。最后在clone()方法中调用了super.clone(),这也意味着无论clone类的继承结构是什么样的
* ,super.clone()直接或间接调用了java.lang.Object类的clone()方法。下面再详细的解释一下这几点。
*应该说第三点是最重要的,仔细观察一下Object类的clone()一个native方法,
*native方法的效率一般来说都是远高于java中的非native方法。这也解释了为什么要用Object中clone()方法而不是先new一个类,
*然后把原始对象中的信息赋到新对象中,虽然这也实现了clone功能。对于第二点,也要观察Object类中的clone()还是一个protected属性的方法。
*这也意味着如果要应用clone()方法,必须继承Object类,在Java中所有的类是缺省继承Object类的,也就不用关心这点了。然后重载clone()方法。
*还有一点要考虑的是为了让其它类能调用这个clone类的clone()方法,重载之后要把clone()方法的属性设置为public。
*那么clone类为什么还要实现Cloneable接口呢?稍微注意一下,Cloneable接口是不包含任何方法的!其实这个接口仅仅是一个标志,而且这个标志也仅仅是针对Object类中clone()方法的,
*如果clone类没有实现Cloneable接口,并调用了Object的clone()方法(也就是调用了super.Clone()方法),
*那么Object的clone()方法就会抛出CloneNotSupportedException异常
*/
public Object clone(){
Bean o = null;
try{
o = (Bean)super.clone();
}catch(CloneNotSupportedException e){
e.printStackTrace();
}
return o;
}
}
序列化bean
package zzg;
import java.io.Serializable;
/**
*
* @ClassName: Bean1
* @Description: TODO(如果支持序列化,必须实现Serializable接口)
* @author 朱争光 1023024917@qq.com
* @date 2013-11-21 下午12:19:45
*
*/
public class Bean1 implements Serializable {
/**
* @Fields serialVersionUID : TODO
*/
private static final long serialVersionUID = 1L;
private String name;
private String pass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPass() {
return pass;
}
public void setPass(String pass) {
this.pass = pass;
}
}
测试main
/**
*
* @Title: testCanShuLeiXi
* @Description: TODO(测试传参类型是引用,还是值传递)
* @return String
* @throws
*/
public static void testCanShuLeiXi(Bean bean) {
bean.setName("14");
}
public static void testCanShuLeiXi1(Bean1 bean) {
bean.setName("14");
}
/**
*
* @Title: cloneObject
* @Description: TODO(序列化实现clone,深度clone,注意serialVersionUID的使用)
* @param obj
* @return
* @throws Exception Object
* @throws
*/
public static Object cloneObject(Object obj) throws Exception{
Object object=new Object();
ByteArrayOutputStream byteOut = new ByteArrayOutputStream();
ObjectOutputStream out = new ObjectOutputStream(byteOut);
out.writeObject(obj);
ByteArrayInputStream byteIn = new ByteArrayInputStream(byteOut.toByteArray());
ObjectInputStream in =new ObjectInputStream(byteIn);
object= in.readObject();
return object;
}
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
/*String s= GetStringToByte(null);
String ss= GetByteToString(s);
System.out.println("1:"+ss);*/
Bean bean=new Bean ();
bean.setName("12");
bean.setPass("123");
Bean beanClone=new Bean ();//测试clone实现复制
beanClone.setName("12");
beanClone.setPass("123");
testCanShuLeiXi(bean);
testCanShuLeiXi((Bean)beanClone.clone());
System.out.println(bean.getName());//说明被修改了。
System.out.println(beanClone.getName());//说明clone后没有被修改
/**
* 下面是序列化实现复制对象
*/
Bean1 bean1=new Bean1 ();
bean.setName("12");
bean.setPass("123");
Bean1 beanClone1=new Bean1 ();//测试clone实现复制
beanClone1.setName("12");
beanClone1.setPass("123");
testCanShuLeiXi1(bean1);
testCanShuLeiXi1((Bean1)cloneObject((Object)beanClone1));
System.out.println(bean1.getName());//说明被修改了。
System.out.println(beanClone1.getName());//说明clone后没有被修改
}
那个好?
那个都不好。。。。
克隆的实现接口Cloneable,并且如果深度克隆的话更麻烦
序列化也得实现接口Serializable,所有对象参数也得实现接口Serializable。。。。。。。。。
好难的说,对于我,还是放弃改传过来的参数算了。。。。。