Java基础-对象的四种创建方式
一、new关键字创建
使用new关键字是我们最常用到的,但是我们应该可以很容易理解到,使用new关键字的方式创建对象容易增加耦合度,在框架中都需要减少new关键字来减少耦合。
示例:
Object obj = new Object();//在Java中使用new关键字我们可以轻易地创建一个对象
二、克隆的方式创建对象
通过克隆对象的方式来创建一个Java对象,这里的克隆使用的是Java顶级父类Object的clone()方法;在克隆时这个对象需要在内存中已经分配了内存空间,克隆后克隆对象得到一个原对象一样大小的内存空间。需要克隆一个对象那么这个类必须实现Cloneable接口。使用clone()方法实现的对象克隆是浅克隆(仅仅克隆这个对象本身,它的引用不克隆)
实现步骤:
1.需要克隆的类实现Cloneable接口
2.重写Object类的clone()方法,修改它的访问权限。
示例:
public class Hello implements Cloneable{
public void say(){
System.out.println("say hello");
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//测试
public class CloneTest{
public static void main(String[] args) {
Frock frock = new Frock();
try {
Frock clone = (Frock) frock.clone();
clone.say();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
三、使用反射的方式创建对象
使用反射的方式创建类的对象:调用Class对象的newInstance()方法;
示例:
public class ReflectionTest {
public static void main(String[] args) {
Class clazz = Hello.class;
try {
Hello hello = (Hello) clazz.newInstance();
hello.say();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}
注意:以上方法,类必须有一个无参数的构造器。类的构造器的访问权限需要足够。
使用反射的方式创建对象(2)
示例:
public class RunClassDemo {
public static void main(String[] args) throws Exception {
Class<Person> clazz = Person.class;
//clazz.newInstance(); // 调用Person中的无参构造
Constructor<Person> constructor =clazz.getConstructor(String.class,int.class);// 调用指定的构造器
// Person p = new Person("张三", 20);
Person person = constructor.newInstance("孙悟空", 5000);// 通过构造器来初始化对象
}
}
四、使用反序列化的方式创建对象
通过反序列化生成对象的过程主要由以下几个步骤:
1、创建一个对象输入流,它可以包装一个其他类型的源输入流,如文件输入流;
2、 通过对象输入流的方法读取对象。
示例:
首先准备一个
public class Person implements Serializable {
private static final long serialVersionUID = 8000853843526378505L;
private String name;
private int age;
private String sex;
public Person(){}
public Person(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
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 getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", sex='" + sex + '\'' +
'}';
}
}
我们先将这个类的一些对象序列化到硬盘上
public void objectSteam(){
try(
ObjectOutputStream outputStream = new ObjectOutputStream(new FileOutputStream("D://person.obj"))
){
outputStream.writeObject(new Person("张三",18,"女"));
outputStream.writeObject(new Person("李四",19,"男"));
outputStream.writeObject(new Person("王五",20,"女"));
outputStream.writeObject(new Person("赵六",21,"男"));
} catch (IOException e) {
e.printStackTrace();
}
}
现在我们将这个类在硬盘中的文件读取到内存中,并创建这个类的对象。这就是反序列化的过程。
public void objectInput(){
try ( ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("D://person.obj"))
){
Object obj =objectInputStream.readObject();
Person person = (Person) obj;
} catch (IOException e) {
e.printStackTrace();
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
注意:在序列化时序列化的对象必须实现了Serializable接口。