1. 程式人生 > >不用構造器也能建立物件

不用構造器也能建立物件

import java.io.ByteArrayInputStream;   
import java.io.ByteArrayOutputStream;   
import java.io.ObjectInputStream;   
import java.io.Serializable;   
public class TestClass implements Serializable{   
    private static final long serialVersionUID = 0L;   
    public TestClass() throws Exception {   
        throw new Exception("哎呀媽呀,異常啦!!!!");   
    }   
    public static void main(String[] args) throws Exception {   
        byte[] head = { -84, -19, 0, 5, 115, 114, 0 };   
        byte[] ass = { 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 120, 112 };   
        String name = TestClass.class.getName();   
        ByteArrayOutputStream baos = new ByteArrayOutputStream();   
        baos.write(head);   
        baos.write(name.length());   
        baos.write(name.getBytes());   
        baos.write(ass);   
        baos.flush();   
        baos.close();   
        ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(baos.toByteArray()));   
        TestClass o = (TestClass) ois.readObject();   
        ois.close();   
        System.out.println("建立物件: " + o);   
    }   
}   
看到這裡先彆著急執行,先看看.你覺得能夠正常執行嗎? 結果是什麼?
-----------------------------------------------------------------------------------
執行結果:  建立物件: [email protected]
CSDN某帖子 寫道 物件建立的幾種方法:
1.使用new關鍵字 2.使用clone方法 3.反射機制 4.反序列化
其中1,3都會明確的顯式的呼叫建構函式
2是在記憶體上對已有物件的影印 所以不會呼叫建構函式
4是從檔案中還原類的物件 也不會呼叫建構函式
上述程式碼就是反序列化的結果
RednaxelaFX 寫道 嗯順帶推薦Effective Java, Second Edition的第74條 引用 Normally, objects are created using constructors;
serialization is an extralinguistic mechanism for creating objects. Whether
you accept the default behavior or override it, deserialization is a “hidden constructor”
with all of the same issues as other constructors.
大體的意思是反序列化有一定的風險.破壞了封裝.相當於一個隱藏的構造器.
RednaxelaFX 寫道 1、Java的例項構造器只負責初始化,不負責建立物件;Java虛擬機器的位元組碼指令的設計也反映了這一點,有一個new指令專門用於建立物件例項,而呼叫例項構造器則使用invokespecial指令。
2、“this”是作為例項構造器的第一個實際引數傳入的。
Java反序列化實際上是呼叫了基類的構造方法.

ObjectStreamClass中呼叫ReflectionFactory.newConstructorForSerialization(cl, cons);
Objectstreamclass程式碼 複製程式碼 收藏程式碼
  1. cons = reflFactory.newConstructorForSerialization(cl, cons);  

根據cl引數(TestClass類的Class物件)和cons引數(基類Object的構造器)建立了一個新的構造器
列印生成的構造器物件,輸出資訊為public java.lang.Object(),表面生成的構造器是TestClass父類Object的無參構造器.
但是呼叫newInstance()的結果卻產生了TestClass類的物件.(おかしい......)

ReflectionFactory.newConstructorForSerialization()例子
Java程式碼
複製程式碼
 收藏程式碼
  1. Constructor superCons = TestClass.class.getSuperclass().getConstructor();   
  2. System.out.println(superCons);   
  3. ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();   
  4. Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);   
  5. System.out.println(c.newInstance());  
        Constructor superCons = TestClass.class.getSuperclass().getConstructor();
        System.out.println(superCons);
        ReflectionFactory reflFactory = ReflectionFactory.getReflectionFactory();
        Constructor c = reflFactory.newConstructorForSerialization(TestClass.class,superCons);
        System.out.println(c.newInstance());

執行結果程式碼 複製程式碼 收藏程式碼
  1. public java.lang.Object()   
  2. [email protected]  

通過基類的方法呼叫生成了子類.繞開了TestClass類的構造方法.生成了看似不可能存在的TestClass物件

-----------------------------------------------------------------------------------
感謝FX,之前一篇關於構造器的詳細論述.傳送門http://rednaxelafx.iteye.com/blog/652719
FX寫的關於本篇的更詳細講解在這裡,傳送門http://rednaxelafx.iteye.com/blog/850082

相關推薦

不用構造建立物件

import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.ObjectInputStream; import java.io.Seri

面試題:不通過建構函式建立物件

不通過建構函式也能建立物件嗎 A. 是 B. 否 答案:A 解析:Java 建立物件的幾種方式(重要): (1) 用 new 語句建立物件,這是最常見的建立物件的方法。 (2) 運用反射手段,呼叫 java.lang.Class 或者 java.l ang.reflect.Constru

不通過建構函式建立物件嗎()

A 是 B 否 答案:A 解析:Java建立物件的幾種方式(重要): (1) 用new語句建立物件,這是最常見的建立物件的方法。 (2) 運用反射手段,呼叫java.lang.Class或者java.lang.reflect.Constructor類的newInstance

不通過建構函式建立物件嗎?

答案:yes 解析:Java建立物件的幾種方式(重要): (1) 用new語句建立物件,這是最常見的建立物件的方法。 (2) 運用反射手段,呼叫java.lang.Class或者java.lang

不用計時可以計時

str bsp syn time reading 異步 () eno async public async void awit(int time=1000) { while(true) {

國稅Tax2 0 執行時錯誤429 ActiveX部件不建立物件的解決辦法

分享一下我老師大神的人工智慧教程!零基礎,通俗易懂!http://blog.csdn.net/jiangjunshow 也歡迎大家轉載本篇文章。分享知識,造福人民,實現我們中華民族偉大復興!        

不用寫程式碼學會採集海量企業電話及郵箱資料

本文主要介紹如何使用后羿採集軟體的智慧模式,免費採集順企網上企業的公司名稱、法人名稱、聯絡電話、企業地址及郵箱等資訊。 採集工具簡介: 后羿採集軟體是一款基於人工智慧技術的網路爬蟲軟體,只需要輸入網址就能夠自動識別網頁資料,無需配置即可完成資料採集,是業內首家支援三種作業系統(包括Windo

秒懂JS物件構造函式和原型物件之間的關係

一、基本概念   1、物件:屬性和方法的集合,即變數和函式的封裝。每個物件都有一個__proto__屬性,指向這個物件的建構函式的原型物件。   2、構造器函式:用於建立物件的函式,通過new關鍵字生成物件。函式名一般首字母大寫的。   3、原型物件:每個函式都有一個prototype屬性,它是一個指向

送福利 愛奇藝 優酷 騰訊等VIP視訊不用開會員觀看

使用方法:點選進入該連結地址,然後去找你要觀看的VIP視訊地址,複製相應地址連結到剛剛開啟的連結裡面的白色框體裡面,即下圖所示的第二個紅色框圈起的框體,然後點選立即觀看,大功告成!!! 須注意:

什麼樣的文章選題自帶話題性,不用追熱點成為熱點?

前一篇文章我們講了寫文章怎麼追熱點、蹭熱點的方法,不少自媒體朋友表示自己文章所屬領域和類別很難結合熱點來寫,難道不蹭熱點就出不了爆文嗎?答案當然是否定的,有些選題是天生自帶話題的。在社會環境的作用下,生活當中的一些話題永遠是最活躍的,很容易成為爆文成為熱點。 比如吐槽自己的工作、單

不用安裝Pycharm讓你的Python IDLE變得高大上

你的PythonIDLE還是這樣的介面麼? 那你就OUT了,現在的IDLE都是這樣的了 深邃的黑色背景還有強大的語法高亮,小編帶你感受心的Python,下面跟著小編一步一步走;本篇文章主要講解的是Windows系統下的,Linux下的會在後期文章中繼續發出 更多P

關於錨點如何不用a標籤實現跳轉

一般情況下的錨點跳轉方式 <a href="#point">點選跳轉</a> <a name="point">我是錨點</a> 但是如果並不是要點選一個具體的文字,而是圖片等怎麼辦呢,可以用a標籤包裹

實時錯誤‘429’:ActiveX控制元件不建立物件

錯誤源: 解決辦法: 註冊此控制元件:點選“開始”→“執行”輸入以下:(regsvr32後有空格) regsvr32 “c:\program Files\common Files\Microsoft Shared\DAO\dao360.dll reg

關於JS錯誤:Automation 伺服器不建立物件

開發了證書模組後,在我和另一位電腦操作都沒有問題的,可偏偏在其它測試機上就出現 js 錯誤:Automation 伺服器不能建立物件。 下面是逐一排錯: (一)檢測根證書的問題,排除。 (二)上網查一下錯誤程式碼:發現報錯機器沒有capicom.dll檔案。於是按照網上一系

面試請假攻略,不用裸辭找到工作

對於騎驢找馬的求職者而言,請假會是個難題,而對於無法享受年休假的新人而言,更是難上加難。有少部分人因為難以請假,直接辭了手頭的工作。什麼樣的理由老闆能准假?企業不批准,怎麼辦?頻繁請假是不是會影響我的實習評分……這一系列問題,讓職場新人很糾結。希望下面的解答幫到那些有請假

ActiveX部件不建立物件:‘dm.dmsoft',程式碼:800A01AD

  解決方法需要兩步: 第一步改登錄檔: HKEY_CLASSES_ROOT\VBSFile\Shell\Open|\Command  將  “%SystemRoot%\System32\WScript.exe” “%1” %* 改為  “%SystemRoot

不用寫程式碼做表單 —— 載入meta即可

# 做增刪改查要寫多少程式碼? > 一個表單一套程式碼,十個表單十套程式碼嗎? 我這麼懶,怎麼會寫這麼多程式碼? 我想做到:即使一百個表單也只需要一套程式碼(而且不需要複製貼上)。實現多個表單,只需要載入不同的meta即可。 Meta結構部分上一個已經寫了,這裡說一下如何做表單。 # 表單demo 先

Java物件學習之建立物件——使用靜態工廠方法代替構造缺點

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。       靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺

Java物件學習之建立物件——使用靜態工廠方法代替構造優點(四)

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。       靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺

Java物件學習之建立物件——使用靜態工廠方法代替構造優點(二)

最近學習Android知識,發現Java好多的基礎知識運用的真的很一般,所以決定在重新梳理一下,現在Kotlin也來了,在Android之路上,留給我看Java的時間不多了。       靜態我們就來簡單介紹一下,使用靜態工廠方法建立物件相較於構造器建立的物件的優缺