创建(实例化)对象的五种⽅式
⽬录
⼀、Java中创建(实例化)对象的五种⽅式
1. ⽤new语句创建对象,这是最常见的创建对象的⽅法;
2. 调⽤对象的clone()⽅法;
3. 运⽤反射⼿段,调⽤java.lang.Class或者java.lang。 reflect.Constructor类的newInstance()实例⽅法。如:Object obj =
Class.forName(“java.lang.Object”)。newInstance();
4. 通过I / O流(包括反序列化),如运⽤反序列化⼿段,调⽤java.io.ObjectInputStream对象的readObject()⽅法;
5. 通过⼯⼚⽅法返回对象,如: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;
}
}
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);
}
运⾏结果:
姓名是:诸葛亮年龄是:30
姓名是:诸葛亮年龄是:30
姓名是:司马懿年龄是:51
3、通过反射对对象进⾏初始化
import flect.Constructor;
import flect.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");
/**
* 调⽤⽆参构造函数,
* 效果上和使⽤wInstance()差不多
* 构造函数⽆参的情况下,可以传⼊⼀个空数组,也可以不传⼊数组
*/
Constructor<Student> con = Constructor();
Student thisIsTestClass = wInstance();
System.out.println("-------------------------------------");
//依然是⽆参构造函数
Class[] paramTypeEmpty = {};
Constructor<Student> con0 = Constructor(paramTypeEmpty);        Object[] paramEmpty = {};
Student thisIsTestClassEmpty = wInstance(paramEmpty);
System.out.println("-------------------------------------");
//getConstructor接受变长参数,以Class数组形式传⼊,
//告诉jdk我们要调⽤哪个构造器
Class[] paramType1 = {String.class};
Constructor<Student> con1 = Constructor(paramType1);
//Constructor实例的newInstance同样也是接受⼀个变长参数,
//参数数组中类型要和getConstructor的类型对应
Object[] params1 = {"ParamOne"};
Student thisIsTestClass1 = wInstance(params1);
System.out.println("-------------------------------------");
//params2中的数据类型要和paramTypes2中的类型相对应
Class[] paramTypes2 = {String.class,Integer.class};
Constructor<Student> con2 = Constructor(paramTypes2);
Object[] params2 = {"ParamOne",2};
Student thisIsTestClass2 = wInstance(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();
}
}
}
运⾏结果:
⽆参构造
-------------------------------------
⽆参构造
-------------------------------------
⼀参构造
-------------------------------------
双参构造
-
------------------------------------
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:/";
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 = adInt();
String str = (adObject();
Student student = (adObject();
System.out.println(i);
System.out.println(str);
System.out.println(student);
obj.close();
in.close();
}catch (Exception e) {
e.printStackTrace();
}
}
}
12345
Today
name=lzq, age=20
5、通过⼯⼚⽅法返回对象

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。