1. 程式人生 > >java基礎-反射詳解與反射是否會破壞類的封裝性見解

java基礎-反射詳解與反射是否會破壞類的封裝性見解

問題:反射是否會破壞類的封裝性見解

       首先,封裝,是將具體的實現細節隱藏,而把功能作為整體提供給類的外部使用,也就是說,公有方法能夠完成類所具有的功能。當別人使用這個類時,如果通過反射直接呼叫私有方法,可能根本實現不了類的功能,甚至可能會出錯,因此通過反射呼叫私有方法可以說是沒有任何用處的,開發人員沒有必要故意去破壞封裝好的類。從這點上看,封裝性並沒有被破壞。(摘自百度問答)
    個人的見解:反射確實可以得到一切 類中的東西(包括私有的屬性、方法等),但是或許不算是破壞封裝,私有方法是為了讓繼承的類無法使用,避免呼叫那些被設為私有的方法出現一些不必要的錯誤。這就是封裝性。反射雖然可以獲取私有方法並使用方法,只能說是其功能強大,可以在保證在呼叫私有方法不會出現錯誤,但是並沒有反射呼叫方法後,該方法就不是私有的了。他仍然是私有的,仍然在子類中不可見。
    對於是否破壞了封裝性,也歡迎大家評論區說明自己的觀點。

//以下內容轉發自blog:http://blog.csdn.net/sinat_38259539/article/details/71799078

反射是框架設計的靈魂

(使用的前提條件:必須先得到代表的位元組碼的Class,Class類用於表示.class檔案(位元組碼))

一、反射的概述

JAVA反射機制是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性;這種動態獲取的資訊以及動態呼叫物件的方法的功能稱為java語言的反射機制。
要想解剖一個類,必須先要獲取到該類的位元組碼檔案物件。而解剖使用的就是Class類中的方法.所以先要獲取到每一個位元組碼檔案對應的Class型別的物件.
以上的總結就是什麼是反射反射就是把java類中的各種成分對映成一個個的Java物件例如:一個類有:成員變數、方法、構造方法、包等等資訊,利用反射技術可以對一個類進行解剖,把個個組成部分對映成一個個物件。
     (其實:一個類中這些成員方法、構造方法、在加入類中都有一個類來描述)如圖是類的正常載入過程:反射的原理在與class物件。熟悉一下載入的時候:Class物件的由來是將class檔案讀入記憶體,併為之建立一個Class物件。
其中這個Class物件很特殊。我們先了解一下這個Class類

二、檢視Class類在java中的api詳解(1.7的API

如何閱讀java中的api詳見java基礎之——String字串處理
Class 類的例項表示正在執行的 Java 應用程式中的類和介面。也就是jvm中有N多的例項每個類都有該Class物件。(包括基本資料型別)Class 沒有公共構造方法。Class
 物件是在載入類時由 Java 虛擬機器以及通過呼叫類載入器中的defineClass 方法自動構造的。也就是這不需要我們自己去處理建立,JVM已經幫我們建立好了。
沒有公共的構造方法,方法共有64個太多了。下面用到哪個就詳解哪個吧

三、反射的使用(這裡使用Student類做演示)

先寫一個Student類。

1、獲取Class物件的三種方式

1.1 Object ——> getClass();
1.2 任何資料型別(包括基本資料型別)都有一個“靜態”的class屬性
1.3 通過Class類的靜態方法:forName(String  className)(常用)

其中1.1是因為Object類中的getClass方法、因為所有類都繼承Object類。從而呼叫Object類來獲取
  1. <span style="font-size:18px;">package fanshe;  
  2. /** 
  3.  * 獲取Class物件的三種方式 
  4.  * 1 Object ——> getClass(); 
  5.  * 2 任何資料型別(包括基本資料型別)都有一個“靜態”的class屬性 
  6.  * 3 通過Class類的靜態方法:forName(String  className)(常用) 
  7.  * 
  8.  */
  9. publicclass Fanshe {  
  10.     publicstaticvoid main(String[] args) {  
  11.         //第一種方式獲取Class物件  
  12.         Student stu1 = new Student();//這一new 產生一個Student物件,一個Class物件。
  13.         Class stuClass = stu1.getClass();//獲取Class物件
  14.         System.out.println(stuClass.getName());  
  15.         //第二種方式獲取Class物件
  16.         Class stuClass2 = Student.class;  
  17.         System.out.println(stuClass == stuClass2);//判斷第一種方式獲取的Class物件和第二種方式獲取的是否是同一個
  18.         //第三種方式獲取Class物件
  19.         try {  
  20.             Class stuClass3 = Class.forName("fanshe.Student");//注意此字串必須是真實路徑,就是帶包名的類路徑,包名.類名
  21.             System.out.println(stuClass3 == stuClass2);//判斷三種方式是否獲取的是同一個Class物件
  22.         } catch (ClassNotFoundException e) {  
  23.             e.printStackTrace();  
  24.         }  
  25.     }  
  26. }</span>  

注意:在執行期間,一個類,只有一個Class物件產生。

三種方式常用第三種,第一種物件都有了還要反射干什麼。第二種需要匯入類的包,依賴太強,不導包就拋編譯錯誤。一般都第三種,一個字串可以傳入也可寫在配置檔案中等多種方法。

2、通過反射獲取構造方法並使用:

student類:
  1. package fanshe;  
  2. publicclass Student {  
  3.     //---------------構造方法-------------------
  4.     //(預設的構造方法)
  5.     Student(String str){  
  6.         System.out.println("(預設)的構造方法 s = " + str);  
  7.     }  
  8.     //無參構造方法
  9.     public Student(){  
  10.         System.out.println("呼叫了公有、無參構造方法執行了。。。");  
  11.     }  
  12.     //有一個引數的構造方法
  13.     public Student(char name){  
  14.         System.out.println("姓名:" + name);  
  15.     }  
  16.     //有多個引數的構造方法
  17.     public Student(String name ,int age){  
  18.         System.out.println("姓名:"+name+"年齡:"+ age);//這的執行效率有問題,以後解決。
  19.     }  
  20.     //受保護的構造方法
  21.     protected Student(boolean n){  
  22.         System.out.println("受保護的構造方法 n = " + n);  
  23.     }  
  24.     //私有構造方法
  25.     private Student(int age){  
  26.         System.out.println("私有的構造方法   年齡:"+ age);  
  27.     }  
  28. }  

共有6個構造方法;測試類:
  1. package fanshe;  
  2. import java.lang.reflect.Constructor;  
  3. /* 
  4.  * 通過Class物件可以獲取某個類中的:構造方法、成員變數、成員方法;並訪問成員; 
  5.  *  
  6.  * 1.獲取構造方法: 
  7.  *      1).批量的方法: 
  8.  *          public Constructor[] getConstructors():所有"公有的"構造方法 
  9.             public Constructor[] getDeclaredConstructors():獲取所有的構造方法(包括私有、受保護、預設、公有) 
  10.  *      2).獲取單個的方法,並呼叫: 
  11.  *          public Constructor getConstructor(Class... parameterTypes):獲取單個的"公有的"構造方法: 
  12.  *          public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"可以是私有的,或受保護、預設、公有; 
  13.  *       
  14.  *          呼叫構造方法: 
  15.  *          Constructor-->newInstance(Object... initargs) 
  16.  */
  17. publicclass Constructors {  
  18.     publicstaticvoid main(String[] args) throws Exception {  
  19.         //1.載入Class物件
  20.         Class clazz = Class.forName("fanshe.Student");  
  21.         //2.獲取所有公有構造方法
  22.         System.out.println("**********************所有公有構造方法*********************************");  
  23.         Constructor[] conArray = clazz.getConstructors();  
  24.         for(Constructor c : conArray){  
  25.             System.out.println(c);  
  26.         }  
  27.         System.out.println("************所有的構造方法(包括:私有、受保護、預設、公有)***************");  
  28.         conArray = clazz.getDeclaredConstructors();  
  29.         for(Constructor c : conArray){  
  30.             System.out.println(c);  
  31.         }  
  32.         System.out.println("*****************獲取公有、無參的構造方法*******************************");  
  33.         Constructor con = clazz.getConstructor(null);  
  34.         //1>、因為是無參的構造方法所以型別是一個null,不寫也可以:這裡需要的是一個引數的型別,切記是型別
  35.         //2>、返回的是描述這個無參建構函式的類物件。
  36.         System.out.println("con = " + con);  
  37.         //呼叫構造方法
  38.         Object obj = con.newInstance();  
  39.     //  System.out.println("obj = " + obj);
  40.     //  Student stu = (Student)obj;
  41.         System.out.println("******************獲取私有構造方法,並呼叫*******************************");  
  42.         con = clazz.getDeclaredConstructor(char.

    相關推薦

    java基礎-反射反射是否破壞封裝見解

    問題:反射是否會破壞類的封裝性見解       首先,封裝,是將具體的實現細節隱藏,而把功能作為整體提供給類的外部使用,也就是說,公有方法能夠完成類所具有的功能。當別人使用這個類時,如果通過反射直接呼叫私有方法,可能根本實現不了類的功能,甚至可能會出錯,因此通過反射呼叫私有方

    Java 基礎 Java 反射機制

    一行代碼 strac classname for 內部 系統資源 用戶 管理 ann 一、什麽是 Java 的反射機制? ??反射(Reflection)是Java的高級特性之一,是框架實現的基礎,定義:JAVA反射機制是在運行狀態中,對於任意一個類,都能夠知道這個類的所有

    java泛型反射泛型通用BaseDao實現

    一 泛型的基本概念 1.1什麼是泛型? 泛型,即“引數化型別”。一提到引數,最熟悉的就是定義方法時有形參,然後呼叫此方法時傳遞實參。那麼引數化型別怎麼理解呢?顧名思義,就是將型別由原來的具體的型別引數化,類似於方法中的變數引數,此時型別也定義成引數形式(可以

    java反射反射作用

    【案例1】通過一個物件獲得完整的包名和類名 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /** * 通過一個物件獲得完整的包名和類名 * */ class Demo

    java基礎---------多執行緒反射

    第一部分多執行緒: java語言是為數不多的支援多執行緒的語言。 程序:當程式進入記憶體執行時,即變成了一個程序。程序是處於執行過程中的程式,並且具有一定的獨立功能,程序是系統進行資源分配和排程的一個獨立單位。 硬碟和記憶體都可以儲存資料。硬碟是持久儲存裝置,記憶體是臨時

    Java 型別資訊反射機制

    > 本文部分摘自 On Java 8 ## RTTI RTTI(RunTime Type Information)執行時型別資訊,能夠在程式執行時發現和使用型別資訊,把我們從只能在編譯期知曉型別資訊並操作的侷限中解脫出來 傳統的多型機制正是 RTTI 的基本使用:假設有一個基類 Shape 和它

    JAVA基礎——異常

    轉自:https://www.cnblogs.com/hysum/p/7112011.html 目錄   一、異常簡介 二、try-catch-finally語句 三、throw和throws關鍵字 四、java中的異常鏈 五、結束語 一、異常簡介

    Java基礎演算法

    查詢和排序演算法是演算法的入門知識,其經典思想可以用於很多演算法當中。因為其實現程式碼較短,應用較常見。所以在面試中經常會問到排序演算法及其相關的問題。但萬變不離其宗,只要熟悉了思想,靈活運用也不是難事。一般在面試中最常考的是快速排序和歸併排序,並且經常有面試官要求現場寫出這兩種排序的程式碼。對這兩

    Java基礎static 關鍵字

    1. 前言 前文中說到了static關鍵字,在Java中這是一個很重要的關鍵字,它有很多的用法,並且在某些特定的情況下使用可以優化程式的效能。本文學習static關鍵字的應用場景。在這之前瞭解變數的型別,變數按作用域分為成員變數和區域性變數,成員變數也就是全域性變數,它是在類中宣告的,不

    迴歸Java基礎 Java 內部類

    今日科技快訊近日,一篇《估值175億的馬蜂窩 竟是一座殭屍和水軍構成的鬼城?》在網路上刷屏。今天

    Java基礎jvm

    一、JVM記憶體結構 1、方法區(Method Area) 別名Non-Heap(非堆)、永久代(Permanent Generation)、持久代(PermGen),各個執行緒共享的記憶體區域,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、以

    Java基礎List

    目錄(本文基於JDK1.8) 1. 前言 我們在日常程式設計中,常常需要集中存放多個數據。這時候,陣列是我們一個很好的選擇,但是陣列在初始化的時候指定了長度之後,這個陣列長度就是不可變的,所以使用陣列的話我們需要實現知道需要儲存物件的數量。如果我們需要儲存一個可

    Java解讀-ThreadLocal應用

    ThreadLocal概念 ThreadLocal 字面意思來看有點像“執行緒的本地實現版本”,實際上真正含義是ThreadLocalVariable(執行緒本地區域性變數),所以把它命名為ThreadLocalVar更加合適。 ThreadLocal 是用

    Java基礎集合(一)

    作為新手,對於集合來講,多少有點感悟 先介紹一下什麼是集合 這是我看的書《java從入門到精通》清華大學出版社 引用裡面的一句話,集合就是一個容器。     對於集合內的各個物件很容易將其存放到集合中,也很容易將其從集合中取出來,還可以按照一定的順序放入。     對集合

    黑馬程式設計師--Java基礎--awt以及簡單應用

    GUI 圖形使用者介面 CLI 命令列使用者介面 Java為GUI提供的物件存在java.Awt和Javax.Swing兩個包中. Java當中如何完成圖形化介面的製作呢? AWT:abstract Window ToolKit.需要呼叫本地

    JAVA反射例項介紹

    我們都知道Java反射很重要,這次我來拋個磚頭!!! 一:反射    反射是在執行狀態中,對於任意一個類,都能夠知道這個類的所有屬性和方法;對於任意一個物件,都能夠呼叫它的任意一個方法和屬性。   使用java的反射,一般有下面三步:     1:獲得你想操作類

    Java動態代理反射

    首先我得先請大家不要誤會,部落格園說轉載的文章放在文章分類裡,原創的文章用隨筆寫,我開先還以為隨筆是拿來寫抒情文的(滑稽),後來才發現不是這樣的,但是自己所有的文章都在文章分類裡了,又懶得搬運,所以我就用js重定向了一下。所以現在標題欄裡進來的都是文章分類哦,大部分都是自己原創的,轉載會註明轉載的url。 廢

    Java 反射

    什麽 tco type 性能 bob 參數 bject 今天 erl   反射反射,程序員的快樂,今天你快樂了嗎?如果你不快樂,沒關系,接下來讓你快樂起來! 一、什麽是反射?  通過百度百科我們可以知道,Java反射就是在運行狀態中,對於任意一個類,都能夠知道這個類的所有屬

    Java學習筆記54(反射

    pos code 重名 java學習筆記 spl catch 兩種 new fig 反射概念: java反射機制是在運行狀態中,對於任意一個類,都能知道所有屬性和方法 對於任意一個對象都能調用它的任意一個方法和屬性,這種動態獲取和調用的功能稱為java的反射機制 實際作

    java反射

    編譯 imp 成員 參數類型 信息 執行方法 定義 所有 c++ 1.什麽是反射 反射是一種間接操作目標對象的機制,在程序程序運行時(動態)獲取或者設置對象自身的信息。只要給定類的名字,就可以通過反射獲取類的所有信息,接著便能調用它的任何一個方法和屬性。 Jav