1. 程式人生 > >java反射詳解之反射作用

java反射詳解之反射作用

【案例1】通過一個物件獲得完整的包名和類名

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 package Reflect; /** * 通過一個物件獲得完整的包名和類名 * */ class Demo{ //other codes... } class hello{ public static void main(String[] args) { Demo demo=new Demo(); System.out.println(demo.getClass().getName());
} }

【執行結果】:Reflect.Demo

新增一句:所有類的物件其實都是Class的例項。

【案例2】例項化Class類物件

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 package Reflect; class Demo{ //other codes... } class hello{ public static void main(String[] args) {
Class<?> demo1=null; Class<?> demo2=null; Class<?> demo3=null; try{ //一般儘量採用這種形式 demo1=Class.forName("Reflect.Demo"); }catch(Exception e){ e.printStackTrace(); } demo2=new Demo().getClass(); demo3=Demo.class; System.out.println("類名稱   "+demo1.getName()); System.out.println(
"類名稱   "+demo2.getName()); System.out.println("類名稱   "+demo3.getName()); } }

【執行結果】:

類名稱   Reflect.Demo

類名稱   Reflect.Demo

類名稱   Reflect.Demo

【案例3】通過Class例項化其他類的物件

通過無參構造例項化物件

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 package Reflect; class Person{ 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 "["+this.name+"  "+this.age+"]"; } private String name; private int age; } class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Person per=null; try { per=(Person)demo.newInstance(); catch (InstantiationException e) { // TODO Auto-generated catch block e.printStackTrace(); catch (IllegalAccessException e) { // TODO Auto-generated catch block e.printStackTrace(); } per.setName("Rollen"); per.setAge(20); System.out.println(per); } }

【執行結果】:

[Rollen  20]

但是注意一下,當我們把Person中的預設的無參建構函式取消的時候,比如自己定義只定義一個有引數的建構函式之後,會出現錯誤:

比如我定義了一個建構函式:

1 2 3 4 public Person(String name, int age) { this.age=age; this.name=name; }

然後繼續執行上面的程式,會出現:

java.lang.InstantiationException: Reflect.Person

    at java.lang.Class.newInstance0(Class.java:340)

    at java.lang.Class.newInstance(Class.java:308)

    at Reflect.hello.main(hello.java:39)

Exception in thread "main" java.lang.NullPointerException

    at Reflect.hello.main(hello.java:47)

所以大家以後再編寫使用Class例項化其他類的物件的時候,一定要自己定義無參的建構函式

【案例】通過Class呼叫其他類中的建構函式(也可以通過這種方式通過Class建立其他類的物件)

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 package Reflect; import java.lang.reflect.Constructor; class Person{ public Person() { } public Person(String name){ this.name=name; } public Person(int age){ this.age=age; } public Person(String name, int age) { this.age=age; this.name=name; } public String getName() { return name; } public int getAge() { return age; } @Override public String toString(){ return "["+this.name+"  "+this.age+"]"; } private String name; private int age; } class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Person per1=null; Person per2=null; Person per3=null; Person per4=null; //取得全部的建構函式 Constructor<?> cons[]=demo.getConstructors(); try{ per1=(Person)cons[0].newInstance(); per2=(Person)cons[1].newInstance("Rollen"); per3=(Person)cons[2].newInstance(20); per4=(Person)cons[3].newInstance("Rollen",20); }catch(Exception e){ e.printStackTrace(); } System.out.println(per1); System.out.println(per2); System.out.println(per3); System.out.println(per4); } }

【執行結果】:

[null  0]

[Rollen  0]

[null  20]

[Rollen  20]

【案例】 

返回一個類實現的介面:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 package Reflect; interface China{ public static final String name="Rollen"; public static  int age=20; public void sayChina(); public void sayHello(String name, int age); } class Person implements China{ public Person() { } public Person(String sex){ this.sex=sex; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } @Override public void sayChina(){ System.out.println("hello ,china"); } @Override public void sayHello(String name, int age){ System.out.println(name+"  "+age); } private String sex; } class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } //儲存所有的介面 Class<?> intes[]=demo.getInterfaces(); for (int i = 0; i < intes.length; i++) { System.out.println("實現的介面   "+intes[i].getName()); } } }

【執行結果】:

實現的介面   Reflect.China

(注意,以下幾個例子,都會用到這個例子的Person類,所以為節省篇幅,此處不再貼上Person的程式碼部分,只貼上主類hello的程式碼)

【案例】:取得其他類中的父類

1 2 3 4 5 6 7 8 9 10 11 12 13 class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } //取得父類 Class<?> temp=demo.getSuperclass(); System.out.println("繼承的父類為:   "+temp.getName()); } }

【執行結果】

繼承的父類為:   java.lang.Object

【案例】:獲得其他類中的全部建構函式

這個例子需要在程式開頭新增import java.lang.reflect.*;

然後將主類編寫為:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Constructor<?>cons[]=demo.getConstructors(); for (int i = 0; i < cons.length; i++) { System.out.println("構造方法:  "+cons[i]); } } }

【執行結果】:

構造方法:  public Reflect.Person()

構造方法:  public Reflect.Person(java.lang.String)

但是細心的讀者會發現,上面的建構函式沒有public 或者private這一類的修飾符

下面這個例子我們就來獲取修飾符

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 class hello{ public static void main(String[] args) { Class<?> demo=null; try{ demo=Class.forName("Reflect.Person"); }catch (Exception e) { e.printStackTrace(); } Constructor<?>cons[]=demo.getConstructors(); for (int i = 0; i < cons.length; i++) { Class<?> p[]=cons[i].getParameterTypes(); System.out.print("構造方法:  "); int mo=cons[i].getModifiers(); System.out.print(Modifier.toString(mo)+" "); System.out.print(cons[i].getName()); System.out.print("("); for(int j=0;j<p.length;++j){ System.out.print(p[j].getName()+" arg"+i); if(j<p.length-1){ System.out.print(","); } } System.out.println("){}"); } } }

【執行結果】:

構造方法:  public Reflect.Person(){}

構造方法:  public Reflect.Person(java.lang.String arg1){}

有時候一個方法可能還有異常,呵呵。下面看看:

1 2 3 4 5 6 7 8 9 10 11 12

相關推薦

java反射反射作用

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

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

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

Java原始碼FileOutputStream

Java原始碼詳解之FileOutputStream類 1.類定義 A file output stream is an output stream for writing data to a File or to a FileDescriptor. Whether or

Java佇列 LinkedList 類

Java佇列詳解之 LinkedList 類 1. 類簡介 類釋義 A collection designed for holding elements prior to processing. Besides basic Collection oper

Java 反射

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

Java學習筆記54(反射

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

java反射

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

Kotlin/Java中的反射

什麼是反射反射是一種計算機處理方式。有程式可以訪問、檢測和修改它本身狀態或行為的這種能力。能提供封裝程式集、型別的物件。對於Java這種OOP語言來講,執行狀態中,我們可以根據“類的部分資訊”來還原“類的全部資訊”,這就是Java中的反射。Java虛擬機器的體系結構Java虛

java 反射通俗易懂

Java的反射機制是Java特性之一,反射機制是構建框架技術的基礎所在。靈活掌握Java反射機制,對大家以後學習框架技術有很大的幫助。  那麼什麼是Java的反射呢?        大家都知道,要讓Java程式能夠執行,那麼就得讓Java類要被Java虛擬機器載入。Java

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

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

java反射--三分鐘學會使用java反射

本篇文章依舊採用小例子來說明,因為我始終覺的,案例驅動是最好的,要不然只看理論的話,看了也不懂,不過建議大家在看完文章之後,在回過頭去看看理論,會有更好的理解。 下面開始正文。 【案例1】通過一個物件獲得完整的包名和類名 1

Java動態代理與反射

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

Java註解,自定義註解,利用反射解析註解

概要 這篇文章將會帶領你瞭解Java註解,註解的使用,註解的解析,利用反射解析執行時註解,相信有一定Java基礎的小夥伴一定會接觸大量的註解,Spring , Hibernate , MyBatis等著名的框架也有很多關於註解方面的應用,對於註解的使用小夥伴們

java反射---反射的理論知識

此篇主要講解下反射的理論概念,另外一篇則是有很多的實際反射的例子,連結如下: 一、JAVA是動態語言嗎? 一般而言,說到動態言,都是指在程式執行時允許改變程式結構或者變數型別,從這個觀點看,JAVA和C++一樣,都不是動態語言。 但JAVA它卻有著一個非常突出的動

Java 型別資訊反射機制

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

spark2.x由淺入深深到底系列六RDD java api

spark 大數據 javaapi 老湯 rdd package com.twq.javaapi.java7; import org.apache.spark.SparkConf; import org.apache.spark.api.java.JavaRDD; import org.

spark2.x由淺入深深到底系列六RDD java api

老湯 spark 大數據 javaapi rdd 學習任何spark知識點之前請先正確理解spark,可以參考:正確理解spark本文詳細介紹了spark key-value類型的rdd java api一、key-value類型的RDD的創建方式1、sparkContext.parall

spark2.x由淺入深深到底系列六RDD java api

spark 大數據 javaapi 老湯 rdd 學習spark任何的知識點之前,先對spark要有一個正確的理解,可以參考:正確理解spark本文對join相關的api做了一個解釋SparkConf conf = new SparkConf().setAppName("appName")

Java定時任務工具Timer篇

java 定時任務 定時 任務調度 什麽 出身 需要 bsp 機制 Java定時任務調度工具詳解 什麽是定時任務調度? ◆ 基於給定的時間點,給定的時間間隔或者給定的執行次數自動執行的任務。 在Java中的定時調度工具? ◆ Timer ◆Quartz Time

python------面向對象進階反射(重點)

code one -- ... set bject pan strip() asa 一.反射 通過字符串映射或者修改程序運行時的狀態,屬性,或者方法。 1.getattr(object,name,default=None) 2.hasattr(object,name