</div>
<!--一个博主专栏付费入口-->
<!--一个博主专栏付费入口结束-->
<link rel="stylesheet" href="https://csdnimg.cn/release/phoenix/template/css/ck_htmledit_views-4a3473df85.css">
<div id="content_views" class="markdown_views prism-atelier-sulphurpool-light">
<!-- flowchart 箭头图标 勿删 -->
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<path stroke-linecap="round" d="M5,0 0,2.5 5,5z" id="raphael-marker-block" style="-webkit-tap-highlight-color: rgba(0, 0, 0, 0);"></path>
</svg>
<p></p><div class="toc"><h3><a name="t0"></a>目录</h3><ul><li><a href="#Java_2" rel="nofollow" target="_self">一、Java中创建(实例化)对象的五种方式</a></li><ul><li><a href="#1new_2clone_11" rel="nofollow" target="_self">1、new关键字创建对象; 2、调用对象的clone()方法创建对象</a></li><li><a href="#3_82" rel="nofollow" target="_self">3、通过反射对对象进行初始化</a></li><li><a href="#4_182" rel="nofollow" target="_self">4、序列化</a></li><li><a href="#5_275" rel="nofollow" target="_self">5、通过工厂方法返回对象</a></li></ul><li><a href="#Java_278" rel="nofollow" target="_self">二、Java中,类的实例化方法有四种途径:</a></li></ul></div><p></p>
一、Java中创建(实例化)对象的五种方式
- 用new语句创建对象,这是最常见的创建对象的方法;
- 调用对象的clone()方法;
- 运用反射手段,调用java.lang.Class或者java.lang。 reflect.Constructor类的newInstance()实例方法。如:Object obj = Class.forName(“java.lang.Object”)。newInstance();
- 通过I / O流(包括反序列化),如运用反序列化手段,调用java.io.ObjectInputStream对象的readObject()方法;
- 通过工厂方法返回对象,如:String str = String.valueOf(23);
1、new关键字创建对象; 2、调用对象的clone()方法创建对象
/** * @ClassName Bigwig * @Description new关键字创建对象; * 调用对象的clone()方法创建对象 * 测试Cloneable接口的使用 * 实例化对象 * @Author lzq * @Date 2019/6/15 19:53 * @Version 1.0 **/ public class Bigwig implements Cloneable{ private String name; private int age;
public Bigwig(String name,int age) { this.name = name; this.age = age; } public String getName () { return name; } public int getAge () { return age; } public void setName(String name) { this.name = name; } public void setAge(int age) { this.age = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } @Override public String toString() { String s = "姓名是:"+this.name+"\t年龄是:"+this.age; return s; }
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
public static void main(String[] args) throws CloneNotSupportedException {
Bigwig p1 = new Bigwig("诸葛亮", 30); //new关键字创建的对象
System.out.println(p1);
Bigwig p2 = null;
p2 = (Bigwig) p1.clone(); 调用对象的clone()方法创建对象
System.out.println(p2);
p2.setAge(51);
p2.setName("司马懿");
System.out.println(p2);
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
运行结果:
姓名是:诸葛亮 年龄是:30
姓名是:诸葛亮 年龄是:30
姓名是:司马懿 年龄是:51
- 1
- 2
- 3
3、通过反射对对象进行初始化
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
/*
- 通过反射对对象进行初始化
- 注意必须有无参数的Constructor
- 实例化Class类然后调用newInstance()方法
*/
class Student{
private Integer age;
private String name;
public Student() {
System.out.println(“无参构造”);
}
public Student(String name) {
System.out.println(“一参构造”);
}
public Student(String name,Integer age) {
System.out.println(“双参构造”);
}
}
public class TestClass {
public static void main(String[] args) {
try{
Class clazz = Class.forName(“com.xagy.lianxi.Student”);
/**
* 调用无参构造函数,
* 效果上和使用class.newInstance()差不多
* 构造函数无参的情况下,可以传入一个空数组,也可以不传入数组
*/
Constructor<Student> con = clazz.getConstructor();
Student thisIsTestClass = con.newInstance();
System.out.println("-------------------------------------");
//依然是无参构造函数
Class[] paramTypeEmpty = {};
Constructor<Student> con0 = clazz.getConstructor(paramTypeEmpty);
Object[] paramEmpty = {};
Student thisIsTestClassEmpty = con0.newInstance(paramEmpty);
System.out.println("-------------------------------------");
//getConstructor接受变长参数,以Class数组形式传入,
//告诉jdk我们要调用哪个构造器
Class[] paramType1 = {String.class};
Constructor<Student> con1 = clazz.getConstructor(paramType1);
//Constructor实例的newInstance同样也是接受一个变长参数,
//参数数组中类型要和getConstructor的类型对应
Object[] params1 = {"ParamOne"};
Student thisIsTestClass1 = con1.newInstance(params1);
System.out.println("-------------------------------------");
//params2中的数据类型要和paramTypes2中的类型相对应
Class[] paramTypes2 = {String.class,Integer.class};
Constructor<Student> con2 = clazz.getConstructor(paramTypes2);
Object[] params2 = {"ParamOne",2};
Student thisIsTestClass2 = con2.newInstance(params2);
System.out.println("-------------------------------------");
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch (NoSuchMethodException e){
e.printStackTrace();
}catch (SecurityException e){
e.printStackTrace();
}catch (InstantiationException e){
e.printStackTrace();
}catch (IllegalAccessException e){
e.printStackTrace();
}catch (IllegalArgumentException e){
e.printStackTrace();
}catch (InvocationTargetException e){
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
- 74
- 75
- 76
- 77
- 78
- 79
- 80
- 81
- 82
- 83
运行结果:
无参构造
-------------------------------------
无参构造
-------------------------------------
一参构造
-------------------------------------
双参构造
-------------------------------------
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
4、序列化
①、序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自 己的各种各样的方法来保存object states,但是Java给你提供一种应该比你自己好的保存对象状态的机制,那就是序列化。
②、什么情况下需要序列化
a)当你想把的内存中的对象状态保存到一个文件中或者数据库中时候;
b)当你想用套接字在网络上传送对象的时候;
c)当你想通过RMI传输对象的时候;
③、相关注意事项
a)序列化时,只对对象的状态进行保存,而不管对象的方法;
b)当一个父类实现序列化,子类自动实现序列化,不需要显式实现Serializable接口;
c)当一个对象的实例变量引用其他对象,序列化该对象时也把引用对象进行序列化;
d)并非所有的对象都可以序列化,,至于为什么不可以,有很多原因了,比如:
Ⅰ.安全方面的原因,比如一个对象拥有private,public等field,对于一个要传输的对象,比如写到文件,或者进行rmi传输 等等,在序列化进行传输的过程中,这个对象的private等域是不受保护的。
Ⅱ. 资源分配方面的原因,比如socket,thread类,如果可以序列化,进行传输或者保存,也无法对他们进行重新的资源分 配,而且,也是没有必要这样实现。
import java.io.*;
/**
- @ClassName TestDemo7
- @Description 对象序列化
- @Author lzq
- @Date 2018/12/11 11:36
- @Version 1.0
**/
class Student implements Serializable {
private static final long serialVersionUID = -88175599799432325L;
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String toString() {
return “name=” + name + “, age=” + age;
}
}
public class TestDemo7 {
public static void main(String[] args) {
String filename = “F:/FHB/serialize.txt”;
serialize(filename);
reverse_serialize(filename);
}
/**
* 序列化
*/
public static void serialize(String filename) {
try {
OutputStream fos = new FileOutputStream(filename);
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeInt(12345);
oos.writeObject("Today");
oos.writeObject(new Student("lzq",20));
oos.close();
fos.close();
}catch (Exception e) {
e.printStackTrace();
}
}
/**
* 反序列化
*/
public static void reverse_serialize(String filename) {
try {
InputStream in = new FileInputStream(filename);
ObjectInputStream obj = new ObjectInputStream(in);
int i = obj.readInt();
String str = (String)obj.readObject();
Student student = (Student)obj.readObject();
System.out.println(i);
System.out.println(str);
System.out.println(student);
obj.close();
in.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
12345
Today
name=lzq, age=20
- 1
- 2
- 3
5、通过工厂方法返回对象
二、Java中,类的实例化方法有四种途径:
1)使用new关键字
2)利用反射,调用Class对象的newInstance()方法
3)调用clone()方法,对现有实例的拷贝
4)利用反序列化,通过ObjectInputStream的readObject()方法反序列化类
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class ClassInstance implements Cloneable, Serializable {
private String str = “测试…”;
public void fun(){
System.out.println(str);
}
public ClassInstance(String str) {
System.out.println("有参类的实例化");
this.str += str;
}
public ClassInstance() {
System.out.println("无参类的实例化");
}
public Object clone() {
return this;
}
}
public class ClassInstanceTest{
public static void main(String[] args) throws ClassNotFoundException, InstantiationException,
IllegalAccessException, IOException,InvocationTargetException, NoSuchMethodException{
//第一种类的实例化方式
ClassInstance ci01 = new ClassInstance(“01”);
ci01.fun();
//第二种类的实例化方式
ClassInstance ci02 = (ClassInstance) Class.forName("com.xagy.lianxi.ClassInstance").newInstance();
ci02.fun();
//第三种类的实例化方式
ClassInstance ci03 = (ClassInstance) ci01.clone();
ci03.fun();
//第四种类的实例化方式
FileOutputStream fos = new FileOutputStream("D:\\ci.txt");
ObjectOutputStream oos = new ObjectOutputStream(fos);
oos.writeObject(ci01);
oos.close();
fos.close();
FileInputStream fis = new FileInputStream("D:\\ci.txt");
ObjectInputStream ois = new ObjectInputStream(fis);
ClassInstance ci04 = (ClassInstance) ois.readObject();
ois.close();
fis.close();
ci04.fun();
System.out.println("--------------------额外测试--------------------");
ClassInstance ci05 = null;
//额外的思考 在第二种类实例化的方式中有没有一种方法实现有参数的构造方式
//获得类的构造信息
Constructor[] ctor = Class.forName("com.xagy.lianxi.ClassInstance").getDeclaredConstructors();
//找到我们需要的构造方法
for(int i=0;i<ctor.length;i++ ){
Class[] cl = ctor[i].getParameterTypes();
if(cl.length == 1){
//实例化对象
ci05 = (ClassInstance) Class.forName("com.xagy.lianxi.ClassInstance").getConstructor(cl).newInstance(new Object[]{"05"});
}
}
ci05.fun();
}
}
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
- 38
- 39
- 40
- 41
- 42
- 43
- 44
- 45
- 46
- 47
- 48
- 49
- 50
- 51
- 52
- 53
- 54
- 55
- 56
- 57
- 58
- 59
- 60
- 61
- 62
- 63
- 64
- 65
- 66
- 67
- 68
- 69
- 70
- 71
- 72
- 73
有参类的实例化
测试...01
无参类的实例化
测试...
测试...01
测试...01
--------------------额外测试--------------------
有参类的实例化
测试...05
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
</div>
<link href="https://csdnimg.cn/release/phoenix/mdeditor/markdown_views-b6c3c6d139.css" rel="stylesheet">
</div>