实例化
目录
- 一、java中创建(实例化)对象的五种方式
- 二、Java中,类的实例化方法有四种途径:
一、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;
}
}
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 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();
}
}
}
运行结果:
无参构造
-------------------------------------
无参构造
-------------------------------------
一参构造
-------------------------------------
双参构造
-------------------------------------
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();
}
}
}
12345
Today
name=lzq, age=20
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();
}
}
有参类的实例化
测试...01
无参类的实例化
测试...
测试...01
测试...01
--------------------额外测试--------------------
有参类的实例化
测试...05
相关阅读
1 接口无法进行实例化。不过接口可以通过匿名接口来操作。直接实现一个接口。但是是匿名的如:public interface Test1Interface {p