Java之不通过构造函数创建一个对象问题
作者:杨·戬
这篇文章主要介绍了Java之不通过构造函数创建一个对象问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
1.调用对象的clone方法,实现一个对象的创建
先来看一个接口
也就是说想要实现类对象的克隆,该类就必须实现这个Cloneable这个接口,才表明调用Object对象中的clone(0方法是有效的
下面直接上代码
Demo2.java
package pxx; public class Demo2 { public static void main(String[] args) throws CloneNotSupportedException { //利用构造创建了一个对象,这里会调用一下无参构造 TestDemo2 testDemo1 = new TestDemo2(); //利用clone()方法创建了一个对象,没有构造方法调用 TestDemo2 testDemo2 = (TestDemo2) testDemo1.clone(); testDemo2.setName("周杰伦"); System.out.println(testDemo1.getName()); System.out.println(testDemo2.getName()); } } class TestDemo2 implements Cloneable{ private String name = "孙悟空"; public TestDemo2() { System.out.println("该类无参构造方法"); } public String getName() { return name; } public void setName(String name) { this.name = name; } //在这个方法里面克隆对象 @Override protected Object clone() throws CloneNotSupportedException { Object o = null; //调用父类的clone方法,返回这个对象 o = (TestDemo2)super.clone(); return o; } }
运行结果:
然后有同学会想到通过反射去实现一个对象也可以,其实他也是调用了对象的构造方法,下面我们来说一下吧
2.利用反射机制来创建一个对象
反射类里面有一个Constructor类,通过里面的newInstance方法可以创建一个对象
先来看一个对象类
Person.java
package domain; public class Person { private String name; private int age; public String a; protected String b; String c; private String d; public Person() { System.out.println("无参构造调用了"); } public Person(String name, int age) { this.name = name; this.age = age; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } @Override public String toString() { return "Person{" + "name='" + name + '\'' + ", age=" + age + ", a='" + a + '\'' + ", b='" + b + '\'' + ", c='" + c + '\'' + ", d='" + d + '\'' + '}'; } public void eat(){ System.out.println("eat..."); } public void eat(String food){ System.out.println("eat..."+food); } }
下面利用反射来获取一个对象
Reflect4.java
package reflect; import domain.Person; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationTargetException; public class Reflect4 { public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //获得class类对象,类文件 Class person = Class.forName("domain.Person"); //利用反射构造一个对象,这里是拿到无参构造函数 Constructor cons1 = person.getConstructor(); Object obj = cons1.newInstance();//其实这里还是调用了构造方法 Person p1 = (Person)obj; p1.setName("张三"); System.out.println(p1.getName()); } }
运行结果:
很明显无参方法被调用了。
3.我们可以通过反序列化去创建一个对象
要通过反序列化一个对象创建一个对象,必须在硬盘上存在一个序列化文件.ser
下面我在D盘中就存在一个关于下面Person类的序列化文件
看我们要通过反序列化创建的这个Person类
package domain; import java.io.Serializable; import java.util.Date; public class Person implements Serializable { String name; int age; String gender; //添加了一个短暂属性,表明这个字段不可别序列化 transient Date birthday; public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getName() { return name; } public void setName(String name) { this.name = name; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getGender() { return gender; } public void setGender(String gender) { this.gender = gender; } }
然后看我们看一下饭序列代码DeserializeTest1.java
package test; import domain.Person; import java.io.*; public class DeserializeTest1 { public static void main(String[] args) { //将文件进行反序列化 Person p = null; //建立一个反序列化对象 //这里是.ser序列化的文件 FileInputStream fis = null; ObjectInputStream objectInputStream = null; try { fis = new FileInputStream("D:/w.ser"); objectInputStream = new ObjectInputStream(fis); p = (Person) objectInputStream.readObject(); } catch (Exception e) { e.printStackTrace(); }finally{ try { objectInputStream.close(); } catch (IOException e) { e.printStackTrace(); } finally { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } //上面就会反序列化之前我们在文件中存放的对象 //然后访问一下之前创建的对象 System.out.println("Name: " + p.getName()); System.out.println("age: " + p.getAge()); System.out.println("gender: " + p.getGender()); System.out.println("birthday: " + p.getBirthday()); } }
运行结果:
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。