/**
* @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
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 con = clazz.getConstructor();
Student thisIsTestClass = con.newInstance();
System.out.println("-------------------------------------");
//依然是无参构造函数
Class[] paramTypeEmpty = {};
Constructor con0 = clazz.getConstructor(paramTypeEmpty);
Object[] paramEmpty = {};
Student thisIsTestClassEmpty = con0.newInstance(paramEmpty);
System.out.println("-------------------------------------");
//getConstructor接受变长参数,以Class数组形式传入,
//告诉jdk我们要调用哪个构造器
Class[] paramType1 = {String.class};
Constructor 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 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();
}
}
}
运行结果:
无参构造
-------------------------------------
无参构造
-------------------------------------
一参构造
-------------------------------------
双参构造
-------------------------------------
①、序列化是干什么的?
简单说就是为了保存在内存中的各种对象的状态(也就是实例变量,不是方法),并且可以把保存的对象状态再读出来。虽然你可以用你自 己的各种各样的方法来保存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();
}
}
}
12345
Today
name=lzq, age=20
单例模式
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
有参类的实例化
测试...01
无参类的实例化
测试...
测试...01
测试...01
--------------------额外测试--------------------
有参类的实例化
测试...05