雜談 論例項化類的第六種方式
你知道幾種例項化一個類的方式?
new?反射?還有呢?
*******************************************美麗的分割線*******************************
筆者總結了一下大概有以下六種方式:
(1)通過構造方法例項化一個類;
(2)通過Class例項化一個類;
(3)通過反射例項化一個類;
(4)通過克隆例項化一個類;
(5)通過反序列化例項化一個類;
(6)通過Unsafe例項化一個類;
Let us 直接上程式碼:
public class InstantialTest { private static Unsafe unsafe; static { try { Field f = Unsafe.class.getDeclaredField("theUnsafe"); f.setAccessible(true); unsafe = (Unsafe) f.get(null); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } } public static void main(String[] args) throws Exception { // 1. 構造方法 User user1 = new User(); // 2. Class,裡面實際也是反射 User user2 = User.class.newInstance(); // 3. 反射 User user3 = User.class.getConstructor().newInstance(); // 4. 克隆 User user4 = (User) user1.clone(); // 5. 反序列化 User user5 = unserialize(user1); // 6. Unsafe User user6 = (User) unsafe.allocateInstance(User.class); System.out.println(user1.age); System.out.println(user2.age); System.out.println(user3.age); System.out.println(user4.age); System.out.println(user5.age); System.out.println(user6.age); } private static User unserialize(User user1) throws Exception { ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("D://object.txt")); oos.writeObject(user1); oos.close(); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("D://object.txt")); // 反序列化 User user5 = (User) ois.readObject(); ois.close(); return user5; } static class User implements Cloneable, Serializable { private int age = 20; public User() { this.age = 10; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } } }
先不要急著往下看,你猜猜上面六種方式列印語句輸出各是多少?
不要看!
不要看!
不要看!
最後列印的結果是這樣:
10
10
10
10
10
0
意不意外?驚不驚喜?
最後一種通過Unsafe例項化的類,裡面的age的值竟然是0,而不是10或者20。
這是因為呼叫Unsafe的allocateInstance()方法只會給物件分配記憶體,並不會初始化物件中的屬性,所以int型別的預設值就是0。
還有其它方式例項化類嗎?歡迎補充!
歡迎關注我的公眾號“彤哥讀原始碼”,檢視更多原始碼系列文章, 與彤哥一起暢遊原始碼的海洋。
相關推薦
雜談 論例項化類的第六種方式
你知道幾種例項化一個類的方式? new?反射?還有呢? *******************************************美麗的分割線******************************* 筆者總結了一下大概有以下六種方式: (1)通過構造方法例項化一個類; (2)通過Class例
雜談 論實例化類的第六種方式
總結 pro img int clone null clas 分享圖片 err 你知道幾種實例化一個類的方式? new?反射?還有呢? 筆者總結了一下大概有以下六種方式: (1)通過構造方法實例化一個類; (2)通過Class實例化一個類; (3)通過反射實例化一個類; (
建立類例項的第六種方式
今天在閱讀springboot原始碼時,發現建立物件不同於以往new關鍵字,Constructor建立,clone,反射呼叫以及反序列化的第六種寫法。 宣告 public class ApplicationConversionService extends FormattingC
Spring例項化bean的三種方式
概述 學習一下Spring IOC bean的三種例項化方式。 構造方法 靜態工廠方法 例項工廠方法 預設構造方法例項化bean 最常用的初始化bean方式 public class Person { private String name; pr
04--Spring例項化Bean的三種方式
上一小節已經新建了Gradle模組用來測試(如果沒有也沒關係,不影響接下來的分析,可以直接在Spring的spring-beans模組下測試即可)。接下來回顧一下Spring中的一些知識點,以便於更好的的分析原始碼,本小節分析一下Spring例項化bean的三種
spring例項化bean的幾種方式
1.使用類構造器實現例項化(bean的自身構造器) 1 <bean id = "orderService" class="cn.itcast.OrderServiceBean"/> 2.使用靜態工廠方法實現例項化 1 <bean id =
Spring例項化Bean的三種方式_例項工廠方法
第一步:Bean3實體 public class Bean3 { } 第二步:工廠 public class Bean3Factory { public Bean3 createBean3(){ return new Bean3();
Spring例項化Bean的三種方式及Bean的型別
1.使用類構造器例項化 [預設的類構造器] 1 <bean id=“orderService" class="cn.itcast.OrderServiceBean"/> 2.使用靜
spring中例項化Bean的三種方式
第一種方式:使用預設無參建構函式 在預設情況下: 它會根據預設無參建構函式來建立類物件。如果bean中沒有預設無參建構函式,將會建立失敗。 <bean id="c
java Class-類載入的三種方法 以及類的初始化的六種方式 及終止執行的方式
1在命令列啟動虛擬機器jvm進行載入,2用class.forname()方法進行動態載入;3用ClassLoader.loadClass()進行動態載入;區別:用二方法載入時,還會對類進行解釋,執行其中的static語句塊; 用三方法時候,static語句塊
Asp.net 靜態化思路第三種實現
做頁面靜態化 網上經常提到的有兩種 1、模板頁+替換的方式 2、偽靜態化,地址重寫 現在我想採用第三種方式,基於網頁抓取技術實現(參考) 1、建立實現類 public class MyUri : System.Uri {
JVM規範中初始化類的5種情況(有且僅有)
類從被載入到虛擬機器記憶體中開始,到卸載出記憶體為止,它的整個生命週期包括:載入、驗證、準備、解析、初始化、使用和解除安裝 7個階段。其中驗證、準備、解析3個部分統稱為連線。 載入、驗證、準備、初始化和解除安裝這5個階段的順序是確定的,類的載入過程必須按照這種順序按部就班的
建立java類並例項化類物件
建立java類並例項化類物件例一1.面向物件的程式設計關注於類的設計2.設計類實際上就是設計類的成員3.基本的類的成員,屬性(成員變數)&方法 面向物件思想的落地法則一:1.設計類,並設計類的成員(成員變數&成員方法)2.通過類,來建立類的物件(也稱作類的例項化) public cl
解釋C++例項化類的指標型別中的new
Intarray * parray = new Intarray();//括號 int * parray = new int(); 兩個都不止是申明,已經初始化了。 第一句是建立(例項化)了一個Intarrya的物件,指標parray指向它。 第二句是建立(分配了)了int型
python:例項化類物件時提示“TypeError: Employee() takes no arguments”的解決方法
最近開始學習python,學習面向物件的知識時遇到一個問題 在建立例項物件時提示“TypeError: Employee() takes no arguments”,百度翻譯了一下,意思是這個類的建構函式不接受引數 找了半天實在不理解哪裡出問題了,明明都在"_
C# 反射通過類名例項化類
在面向物件程式設計的時候,會遇到這樣的問題,一個父類有多個子類,需要建立一個父類的物件,再後面根據條件去把該物件例項化具體的某個子類,然後進行操作。當然用if else 或者switch來做也可以,但是後期擴充套件性不好,特別是要把這些類封裝成dll提供給被人用
php實現例項化類後自動進行錯誤以及異常處理(簡易版)
<?php class App { public function __construct() { /* * ini_set 設定配置項 * display_errors 是否在頁面顯示錯誤資訊 *
Java 多執行緒傳值有三種方式,以及另類的第四種方式
現在博主的需求是:有可能在同一個執行緒類執行不一樣的程式。上邊兩個紅框中的cron4j排程器使用的是一個,根據引數不同來執行的。如果我點選後邊的手動執行一次,按照我上邊給出的java程式碼是無法實現的。看下邊的新的程式碼: (adsbygoogle = window.adsbygoo
Delphi 通過字串例項化類
D2007 通過字串建立窗體類物件 1、需要在程式初始化的時候將類註冊,註冊到物件 RegGroups:(TRegGroups)中,以便查詢。 註冊類使用的函式:RegisterClass ,窗體初始化操作放在initialization 中。 un
例項化類,怎麼限制只能在堆或棧分配!
昨天一個同學去網易面試C++研發,問到了這麼一個問題:如何限制一個類物件只在棧(堆)上分配空間? 一般情況下,編寫一個類,是可以在棧或者堆分配空間。但有些時候,你想編寫一個只能在棧或者只能在堆上面分配空間的類。這能不能實現呢?仔細想想,其實也是可以滴。 在C