Java 创建对象的四种方式
来源:互联网 发布:wow淘宝刷坐骑会封号吗 编辑:程序博客网 时间:2024/05/20 07:36
Java 创建对象的四种方式
- 通过new关键字生成对象
- 通过java反射机制创建对象
- 通过clone对象生成新对象
- 通过序列化生成新对象
通过new关键字生成对象
新建一个Student类,如下
public class Student{ private String name; private Float grade; public Student(){ } public Student(String name, Float grade){ this.name = name; this.grade = grade; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Float getGrade() { return grade; } public void setGrade(Float grade) { this.grade = grade; }}
通过new关键字创建对象
Student s = new Student(); //调用无参构造器Student s2 = new Student("Han Meimei", 15f) //调用有参构造器
通过java反射机制创建对象
使用Class.getInstance()
创建新的对象,如下
Student s3 = Student.class.getInstance();Student s4 = (Student)Class.forName("Student").getInstance();
使用这种方式是调用的类的无参构造器生成的对象,如果想要调用有参构造器生成对象,应该怎么办?
使用Class.getConstructor()
方法
Constructor<Student> studentConstructor = Student.class.getConstructor(String.class, Float.class);Student s5 = studentConstructor.newInstance("Han Meimei", 15f);
查看Class.getInstance()
方法,内部实现是通过调用类的无参构造器生成新的对象的。
所以使用Class.getInstance()
方法,要确保类有public的无参构造器。
通过clone对象生成新对象
要使用Object.clone()
生成新对象,类必须实现接口Cloneable
,并且重写clone()
方法。
修改Student如下
public class Student implements Cloneable{ ... @Override public Object clone() throws CloneNotSupportedException { return super.clone(); } //重写toString方便通过打印检查结果 @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", grade=" + grade + '}'; }}
使用clone()
生成新的类,如下
Student s6 = (Student)s5.clone();System.out.println(s6.toString());
可以查看命令行,新生成的对象s6完整复制了s5的属性
Student{name='Han Meimei', grade=15.0}
如果给Student新加一个属性,List<String> subjects
表示学生参加的学科的列表。这时候调用super.clone()
,能成功拷贝s5的subjects属性里的值到s6里了么?
修改Student类添加属性subjects和对应个getter,setter方法如下
public class Student implements Cloneable{ ... private List<String> subjects; ... public List<String> getSubjects() { return subjects; } public void setSubjects(List<String> subjects) { this.subjects = subjects; } }
给s5的subjects属性赋值,并且通过clone()
重新生成s6
List<String> subjects = new ArrayList<String>(); subjects.add("语文"); subjects.add("数学"); s5.setSubjects(subjects); Student s6 = (Student) s5.clone(); System.out.println(s6.toString());
查看s6,s6成功复制了s5的subjects属性
Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学]}
但是我们发现s6比s5多修了一门学科-英语,所以需要修改s6
的subjects。
s6.getSubjects().add("英语");System.out.println(s6.toString());
查看s6
Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学, 英语]}
这时候我们再打印s5看看
System.out.println(s5);
命令行输出
Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学, 英语]}
发现s5的subjects属性也改变了!!
这个地方就是一个要注意的坑,查看clone()
源码的注释发现:
* performs a "shallow copy" of this object, not a "deep copy" operation.
什么意思呢?
这个是浅拷贝,不是深拷贝。当拷贝s5的subjects属性只是拷贝了引用。s6的subjects属性和s5的subjects属性指向的是同一块地址,修改其中一个内容,必会导致另一个的修改。
如何解决这个问题?
重新修改clone()
方法,
@Overridepublic Object clone() throws CloneNotSupportedException { Student newStudent = (Student) super.clone(); if(null != this.getSubjects()){ List<String> newSubjects = new ArrayList<>(); newSubjects.addAll(this.getSubjects()); newStudent.setSubjects(newSubjects); } return newStudent;}
重新执行拷贝的代码
Student s6 = (Student) s5.clone();s6.getSubjects().add("英语");System.out.println(s6);System.out.println(s5);
查看命令行输出
Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学, 英语]}Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学]}
s5的subjects属性并没有改变。
通过序列化生成新对象
通过序列化生成新对象,类必须实现接口Serializable
修改Student类如下
public class Student implements Cloneable, Serializable{ private static final long serialVersionUID = 1L; ...}
我们将s6转化成二进制写入”Student6.obj”文件中,再通过读取该文件生成新的对象s7
try(ObjectOutputStream objectOutputStream = new ObjectOutputStream(new FileOutputStream("Student6.obj")); ObjectInputStream objectInputStream = new ObjectInputStream(new FileInputStream("Student6.obj"))){ objectOutputStream.writeObject(s6); Student s7 = (Student) objectInputStream.readObject(); System.out.println(s7); } catch (IOException e) { e.printStackTrace(); }
查看命令行输出,我们可以看到s7完整生成了。
Student{name='Han Meimei', grade=15.0, subjects=[语文, 数学, 英语]}
- java创建对象的四种方式
- Java 创建对象的四种方式
- Java创建对象的四种方式
- Java创建对象的四种方式
- Java 创建对象的四种方式
- java创建对象的四种方式
- Java 创建对象的四种方式
- java创建对象的四种方式
- JAVA创建对象的四种方式
- Java中创建对象的四种方式
- Java中创建对象的四种方式
- Java中创建对象的四种方式
- JAVA中创建对象的四种方式
- JAVA中创建对象的四种方式
- JAVA中创建对象的四种方式
- javascript的四种创建对象方式
- JavaScript创建对象的四种方式
- 创建对象的四种方式
- 91-DecodeWays
- Linux Ida and Ird 源码分析
- 网络基础--DNS
- 94-Binary Tree Inorder Traversal
- LTE CAT-M1 vs NB-IoT 风云对决
- Java 创建对象的四种方式
- 95-Unique Binary Search Trees II
- Maven 实战 附录
- 96-Unique Binary Search Trees
- 调研tcp定时器
- 2017年影响SQL Server DBA的四大趋势
- 【C语言】一个数组中只有两个数字是出现一次,其他所有数字都出现了两次,找出这两个数字!
- 98_ValidateBinarySearchTree
- Moving Averages(5): Strategies