Java:建立物件的四種顯示方式
阿新 • • 發佈:2020-12-18
Java:建立物件的四種顯示方式
總所周知,Java是一門純面向物件的語言,而面向物件是如何建立物件的呢,筆者這邊通過程式碼方式簡單的描述一下(相關程式碼在附錄中展現)。
1、使用new關鍵字直接建立物件
毫無疑問,使用new關鍵字是最簡單的建立物件的方式
//類名 變數名 = new 類名();
User user = new User();
通過new關鍵字系統會呼叫預設的構造方法,即無參構造方法。
2、通過反射建立物件
在反射機制中可以通過以下兩種方式建立物件
2.1、Class類的newInstance方法
//類名 變數名 = (類名)Class.forName("路徑").newInstance();
User user1 = (User)Class.forName("com.instance.pojo.User").newInstance();
//or 類名 變數名 = 類名.class.newInstance();
User user2 = User.class.newInstance();
2.2、Constructor類的newInstance()方法
//類名 變數名 = 類名.class.getContrustor().newInstance();
User user = User.class.getConstructor().newInstance();
上述兩種是通過反射機制實現建立物件的方式,和new出來的物件一樣,反射生成的物件也會呼叫無參構造。(注:當前筆者功力不夠,還未能探究原始碼,先在此立下flag,一定會把建立物件原始碼過程展示出來)
3、通過clone建立物件
通過clone建立物件,首先要在即將建立物件的類實現Cloneable介面
//先建立一個物件,用於被克隆
User user = new User();
//類名 變數名2 = (類名)變數名1.clone();
User userClone = (User)user.clone();
值得一提的是,在克隆物件的時候,是通過jvm建立一個新的物件,並且把原來物件的全部內容(包括建構函式、setter、getter方法等)複製一份到新的物件,且此方法不會呼叫無參構造。
4、通過反序列化建立物件
通過反序列化建立物件,首先要在即將建立物件的類實現Serializable介面
User user1 = new User();
FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(user1);
objectOutputStream.flush();
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream("test.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
User user2 = (User)objectInputStream.readObject();
反序列化生成的物件和clone一樣,都會建立一個新的物件,且不會呼叫無參構造。
5、總結:建立物件的四種顯示方式
建立方式 | 是否呼叫了無參構造 | 是否呼叫了介面 |
---|---|---|
new關鍵字 | 是 | 否 |
反射機制 | 是 | 否 |
clone | 否 | 是 |
反序列化 | 否 | 是 |
附錄:
程式碼結構:
com.instance.pojo.User
public class User implements Cloneable, Serializable {
private int id;
private String name;
public User() {
System.out.println("==無參構造==");
}
public User(int id, String name) {
this.id = id;
this.name = name;
System.out.println("==有參構造==");
}
@Override
public Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
com.instance.test.ByNewTest
public class ByNewTest {
public static void main(String[] args) {
User user = new User();
}
}
com.instance.test.ByReflectTest
public class ByReflectTest {
public static void main(String[] args) {
//第一種情況反射,利用Class類的newInstance方法
//形式一:
try {
User user1 = (User)Class.forName("com.instance.pojo.User").newInstance();
} catch (InstantiationException | ClassNotFoundException | IllegalAccessException e) {
e.printStackTrace();
}
//形式二:
try {
User user2 = User.class.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
//第二種情況,使用Constructor類的newInstance方法
try {
// Constructor<User> constructor = User.class.getConstructor();
// constructor.newInstance();
User user3 = User.class.getConstructor().newInstance();
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException e) {
e.printStackTrace();
}
}
}
com.instance.test.ByCloneTest
public class ByCloneTest{
public static void main(String[] args){
User user1 = new User();
try {
User user2 = (User) user1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
}
}
com.instance.test.ByDeserializeTest
public class ByDeserializeTest {
public static void main(String[] args) throws IOException, ClassNotFoundException {
User user1 = new User();
FileOutputStream fileOutputStream = new FileOutputStream("test.txt");
ObjectOutputStream objectOutputStream = new ObjectOutputStream(fileOutputStream);
objectOutputStream.writeObject(user1);
objectOutputStream.flush();
objectOutputStream.close();
FileInputStream fileInputStream = new FileInputStream("test.txt");
ObjectInputStream objectInputStream = new ObjectInputStream(fileInputStream);
User user2 = (User)objectInputStream.readObject();
System.out.println("user1與user2是否相同?--"+(user1==user2));
}
}