Java之不通過構(gòu)造函數(shù)創(chuàng)建一個(gè)對(duì)象問題
1.調(diào)用對(duì)象的clone方法,實(shí)現(xiàn)一個(gè)對(duì)象的創(chuàng)建
先來看一個(gè)接口

也就是說想要實(shí)現(xiàn)類對(duì)象的克隆,該類就必須實(shí)現(xiàn)這個(gè)Cloneable這個(gè)接口,才表明調(diào)用Object對(duì)象中的clone(0方法是有效的
下面直接上代碼
Demo2.java
package pxx;
public class Demo2 {
public static void main(String[] args) throws CloneNotSupportedException {
//利用構(gòu)造創(chuàng)建了一個(gè)對(duì)象,這里會(huì)調(diào)用一下無參構(gòu)造
TestDemo2 testDemo1 = new TestDemo2();
//利用clone()方法創(chuàng)建了一個(gè)對(duì)象,沒有構(gòu)造方法調(diào)用
TestDemo2 testDemo2 = (TestDemo2) testDemo1.clone();
testDemo2.setName("周杰倫");
System.out.println(testDemo1.getName());
System.out.println(testDemo2.getName());
}
}
class TestDemo2 implements Cloneable{
private String name = "孫悟空";
public TestDemo2() {
System.out.println("該類無參構(gòu)造方法");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//在這個(gè)方法里面克隆對(duì)象
@Override
protected Object clone() throws CloneNotSupportedException {
Object o = null;
//調(diào)用父類的clone方法,返回這個(gè)對(duì)象
o = (TestDemo2)super.clone();
return o;
}
}運(yùn)行結(jié)果:

然后有同學(xué)會(huì)想到通過反射去實(shí)現(xiàn)一個(gè)對(duì)象也可以,其實(shí)他也是調(diào)用了對(duì)象的構(gòu)造方法,下面我們來說一下吧
2.利用反射機(jī)制來創(chuàng)建一個(gè)對(duì)象
反射類里面有一個(gè)Constructor類,通過里面的newInstance方法可以創(chuàng)建一個(gè)對(duì)象

先來看一個(gè)對(duì)象類
Person.java
package domain;
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person() {
System.out.println("無參構(gòu)造調(diào)用了");
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", a='" + a + '\'' +
", b='" + b + '\'' +
", c='" + c + '\'' +
", d='" + d + '\'' +
'}';
}
public void eat(){
System.out.println("eat...");
}
public void eat(String food){
System.out.println("eat..."+food);
}
}下面利用反射來獲取一個(gè)對(duì)象
Reflect4.java
package reflect;
import domain.Person;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Reflect4 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//獲得class類對(duì)象,類文件
Class person = Class.forName("domain.Person");
//利用反射構(gòu)造一個(gè)對(duì)象,這里是拿到無參構(gòu)造函數(shù)
Constructor cons1 = person.getConstructor();
Object obj = cons1.newInstance();//其實(shí)這里還是調(diào)用了構(gòu)造方法
Person p1 = (Person)obj;
p1.setName("張三");
System.out.println(p1.getName());
}
}運(yùn)行結(jié)果:

很明顯無參方法被調(diào)用了。
3.我們可以通過反序列化去創(chuàng)建一個(gè)對(duì)象
要通過反序列化一個(gè)對(duì)象創(chuàng)建一個(gè)對(duì)象,必須在硬盤上存在一個(gè)序列化文件.ser
下面我在D盤中就存在一個(gè)關(guān)于下面Person類的序列化文件

看我們要通過反序列化創(chuàng)建的這個(gè)Person類
package domain;
import java.io.Serializable;
import java.util.Date;
public class Person implements Serializable {
String name;
int age;
String gender;
//添加了一個(gè)短暫屬性,表明這個(gè)字段不可別序列化
transient Date birthday;
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}然后看我們看一下飯序列代碼DeserializeTest1.java
package test;
import domain.Person;
import java.io.*;
public class DeserializeTest1 {
public static void main(String[] args) {
//將文件進(jìn)行反序列化
Person p = null;
//建立一個(gè)反序列化對(duì)象
//這里是.ser序列化的文件
FileInputStream fis = null;
ObjectInputStream objectInputStream = null;
try {
fis = new FileInputStream("D:/w.ser");
objectInputStream = new ObjectInputStream(fis);
p = (Person) objectInputStream.readObject();
} catch (Exception e) {
e.printStackTrace();
}finally{
try {
objectInputStream.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
//上面就會(huì)反序列化之前我們?cè)谖募写娣诺膶?duì)象
//然后訪問一下之前創(chuàng)建的對(duì)象
System.out.println("Name: " + p.getName());
System.out.println("age: " + p.getAge());
System.out.println("gender: " + p.getGender());
System.out.println("birthday: " + p.getBirthday());
}
}運(yùn)行結(jié)果:

總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)優(yōu)雅的參數(shù)校驗(yàn)方法詳解
這篇文章主要為大家詳細(xì)介紹了Java語言如何實(shí)現(xiàn)優(yōu)雅的參數(shù)校驗(yàn),文中的示例代碼講解詳細(xì),對(duì)我們學(xué)習(xí)Java有一定是幫助,需要的可以參考一下2022-06-06
bug解決Failed_to_execute_goal_org.springframework
這篇文章主要為大家介紹了bug解決Failed_to_execute_goal_org.springframework,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-09-09
SpringBoot利用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問題
dynamic-datasource-spring-boot-starter 是一個(gè)用于在 Spring Boot 項(xiàng)目中實(shí)現(xiàn)動(dòng)態(tài)數(shù)據(jù)源切換的工具,下面我們看看如何使用dynamic-datasource-spring-boot-starter解決多數(shù)據(jù)源問題吧2025-03-03
Spring Boot 如何將 Word 轉(zhuǎn)換為 PDF
這篇文章主要介紹了Spring Boot將Word轉(zhuǎn)換為 PDF,本文通過示例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08

