最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

JAVA編程不能不知道的反射用法總結(jié)

 更新時(shí)間:2021年07月17日 15:39:13   作者:蛋撻學(xué)姐  
這篇文章主要介紹了Java反射技術(shù)原理與用法,結(jié)合實(shí)例形式分析了Java反射技術(shù)的基本概念、功能、原理、用法及操作注意事項(xiàng),需要的朋友可以參考下

下面對(duì)Java反射的基礎(chǔ)知識(shí)進(jìn)行說明和總結(jié):

首先定義一個(gè)MyBase類,其中有私有字段,也有公有字段。同時(shí)也有公有方法和私有方法。MyBase類示例如下:

package com.hwdev.demo;
/**
 * 基類示例
 * @author wangming
 */
public class MyBase {
    //公有字段  
    public int version  = 1;
    //私有字段
    private String date = "2021-05-18" ;
    //公有方法   
    public void say2(String msg){
	System.out.println("Hello " + msg);
    }
    //私有方法
    private String getData(){
        return this.date;
    }
}//加入Java開發(fā)交流君樣:756584822一起吹水聊天

這里再定義一個(gè)Hello類,它繼承自MyBase類,通過繼承主要用于驗(yàn)證一下反射對(duì)于父類、子類的反射用法。

package com.hwdev.demo;
/**
 *
 * @author wangming
 */
public class Hello extends MyBase {
    public String author = "JackWang" ;
    public int version  = 1;
    private String company = "kzcloud" ;
    public void say(String msg){
	     System.out.println("Hello " + msg);
    }
    public void setAuthor(String author){
	    this.author = author;
    }
    public String getAuthor(){
        return this.author;
    }
    private int getVersion(){
        return this.version;
    }
}

關(guān)于Java反射,功能強(qiáng)大的就是可以通過字符串配置來動(dòng)態(tài)從系統(tǒng)中調(diào)用方法或者修改其中某個(gè)對(duì)象的字段值,而Class.forName方法即可以通過傳入類全路徑字符串名稱來獲取對(duì)應(yīng)的Class對(duì)象,非常的方便。另外通過getField方法和GetMethod方法可以獲取指定字段和方法,并動(dòng)態(tài)調(diào)用。

package com.hwdev.demo;
import java.lang.reflect.*;
import java.util.Arrays;
/**
 * 反射第一種用法 Class.forName
 * @author wangming
 */
public class ReflectDemo01 {
     public static void Test() {
        try
        {
            //通過字符串全路徑類名查找Class
            Class helloC = Class.forName("com.hwdev.demo.Hello"); 
            //獲取所有公有的字段數(shù)組,私有的無法獲取   
            Field [] fields = helloC.getFields();
            //打印字段數(shù)組內(nèi)容//加入Java開發(fā)交流君樣:756584822一起吹水聊天
            System.out.println(Arrays.toString(fields));
            //[public java.lang.String com.hwdev.demo.Hello.author, public int com.hwdev.demo.Hello.version]
            //實(shí)例化
            Object obj = helloC.newInstance();
            //獲取特定字段,比遍歷Field[]效率更高
            Field f = helloC.getField("author");
            if (f != null){
                //關(guān)閉安全檢查,提高效率
                f.setAccessible(true);
                //獲取字段author內(nèi)容
                String author = (String)f.get(obj);
                System.out.println("author=" + author);
                //author=JackWang
            }
            //獲取所有公有的方法數(shù)組,私有的無法獲取 
            Method [] methods = helloC.getMethods();
            //打印方法數(shù)組內(nèi)容,子類等方法也可以獲取到
            System.out.println(Arrays.toString(methods));
            //本類所有方法
            Method [] methods2 = helloC.getDeclaredMethods();
            //打印方法數(shù)組內(nèi)容
            System.out.println(Arrays.toString(methods2));
            //獲取特定方法,第二個(gè)參數(shù)String.class為say方法的參數(shù)類型
            //say(java.lang.String)
            Method m = helloC.getDeclaredMethod("say",String.class); 
            if (m != null){
                //關(guān)閉安全檢查,提高效率
                m.setAccessible(true);
                //獲取字段author內(nèi)容
                Object returnValue = m.invoke(obj, new Object[]{"Java"});
                //Hello Java
                if (returnValue!=null){
                    System.out.println("returnValue =" + returnValue);    
                }
            }//加入Java開發(fā)交流君樣:756584822一起吹水聊天
        }catch(ClassNotFoundException | SecurityException ex){
            ex.printStackTrace();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }    
}

這里需要注意:xxx.getMethods()方法默認(rèn)情況下,會(huì)返回本類、父類、父接口的公有方法,而xxx.getDeclaredMethods()返回本類的 所有方法,包括私有的方法。同理,反射API中其他getXXX和getDeclaredXXX的用法類似。

package com.hwdev;
import com.hwdev.demo.ReflectDemo01;
/**
 * 
 * @author wangming
 */
public class Main {
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        //反射第一種用法 Class.forName
        ReflectDemo01.Test();
    }    
}

執(zhí)行程序,輸出的結(jié)果如下:

[public java.lang.String com.hwdev.demo.Hello.author, public int com.hwdev.demo.Hello.version, public int com.hwdev.demo.MyBase.version] author=JackWang [public void com.hwdev.demo.Hello.say(java.lang.String), public void com.hwdev.demo.Hello.setAuthor(java.lang.String), public java.lang.String com.hwdev.demo.Hello.getAuthor(), public void com.hwdev.demo.MyBase.say2(java.lang.String), public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()] [public void com.hwdev.demo.Hello.say(java.lang.String), public void com.hwdev.demo.Hello.setAuthor(java.lang.String), public java.lang.String com.hwdev.demo.Hello.getAuthor(), private int com.hwdev.demo.Hello.getVersion()] Hello Java

從輸出結(jié)果上來看,Field [] fields = helloC.getFields();不但可以獲取Hello類的公有字段,還可以獲取到父類MyBase的公有字段:com.hwdev.demo.MyBase.version

而Method [] methods2 = helloC.getDeclaredMethods();則可以獲取本類,即Hello類所有的方法,包括公有的方法和私有的方法。因此,Java反射可以訪問類的私有字段和方法,從而暴露內(nèi)部的信息,這也是Java反射有安全問題的原因。

由于Java方法支持重載,因此同名的方法可以存在多個(gè),即參數(shù)不同,因此在用反射調(diào)用方法時(shí),需要指定方法的參數(shù)類型,這樣就可以明確調(diào)到的具體是哪個(gè)方法簽名,如`Method m = helloC.getDeclaredMethod("say",String.class); `調(diào)用的是`public void com.hwdev.demo.Hello.say(java.lang.String) `。

除了可以用Class.forName來進(jìn)行反射外,還可以通過如下方式來獲取反射對(duì)象:

Hello hello = new Hello();
Class helloC = hello.getClass();
Field [] fields = helloC.getFields();
//
Class helloC = Hello.class; 
Field [] fields = helloC.getFields();

下面介紹一下如何用Java反射修改私有字段和調(diào)用私有方法的示例:

package com.hwdev.demo;
import java.lang.reflect.*;
/**
 * 反射訪問私有字段和方法
 * @author wangming
 */
public class ReflectDemo02 {
   //加入Java開發(fā)交流君樣:756584822一起吹水聊天 
     public static void Test() {
        try
        {
            //通過已有類查找Class         
            Class helloC = Hello.class; 
            //實(shí)例化
            Object obj = helloC.newInstance();
            //獲取特定私有字段
            Field f = helloC.getDeclaredField("company");
            if (f != null){
                //私有必須開啟
                f.setAccessible(true);
                //設(shè)置私有字段值
                f.set(obj, "newKZ");
                //獲取字段author內(nèi)容
                String fv = (String)f.get(obj);
                System.out.println("company=" + fv);
                //company=newKZ
            } 
            //獲取私有方法
            Method m = helloC.getDeclaredMethod("getVersion", null); 
            if (m != null){
                //私有必須開啟
                m.setAccessible(true);
                Object returnValue = m.invoke(obj, null);
                if (returnValue!=null){
                    //returnValue =1
                    System.out.println("returnValue =" + returnValue);    
                }
            }
        }catch(SecurityException ex){
            ex.printStackTrace();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }    
}

另外,Java反射可以獲取注解信息,這個(gè)對(duì)于ORM框架來講,用的非常多。

package com.hwdev.demo;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 注解示例
 * @author wangming
 */
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ORMAnnotation {
    public String FieldName();
    public String FieldType();
}

其中,@Retention(RetentionPolicy.RUNTIME)表示注解可以在運(yùn)行時(shí)通過反射訪問。@Target(ElementType.FIELD) 表示這個(gè)注解只能用在字段上面。同理,可以把FIELD改為Type或者M(jìn)ethod等。

package com.hwdev.demo;
import java.lang.annotation.Annotation;
import java.lang.reflect.*;
/**
 * 反射或者字段注解
 * @author wangming
 *///加入Java開發(fā)交流君樣:756584822一起吹水聊天
public class ReflectDemo03 {
     public static void Test() {
        try
        {
            Class helloC = Class.forName("com.hwdev.demo.HelloAnnotation");      
            Field[] fields = helloC.getDeclaredFields();
            for(Field f : fields){
                 //關(guān)閉安全檢查,提高效率
                f.setAccessible(true);
                Annotation ann = f.getAnnotation(ORMAnnotation.class);
                if(ann instanceof ORMAnnotation){
                    ORMAnnotation ormAnn = (ORMAnnotation) ann;
                    System.out.println("FieldName=" + ormAnn.FieldName());
                    System.out.println("FieldType=" + ormAnn.FieldType());
                }
            }          
        }catch(ClassNotFoundException | SecurityException ex){
            ex.printStackTrace();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }    
}

執(zhí)行此示例,則輸出如下:

FieldName=f_author FieldType=varchar(50) FieldName=f_ver FieldType=int

再次,介紹一下如何用反射獲取方法參數(shù)個(gè)數(shù)和類型,其中包含泛型的信息獲?。?/p>

package com.hwdev.demo;
import java.util.ArrayList;
import java.util.List;
/**
 * 泛型示例
 * @author wangming
 */
public class GenericCls {
   protected List<String> myList = new ArrayList(); 
   public GenericCls(int size){      
       for(int i = 0;i<size;i++){
           myList.add("item"+i);
       }
   }
   public  List<String> getList(){ 
      return this.myList;
   }
   public String getList(int idx){ 
      return this.myList.get(idx);
   }
}
package com.hwdev.demo;
import java.lang.reflect.*;
/**
 * 反射獲取方法參數(shù)
 * @author wangming
 */
public class ReflectDemo05 {
     public static void Test() {
        try
        {
        //加入Java開發(fā)交流君樣:756584822一起吹水聊天
            Class helloC = Class.forName("com.hwdev.demo.GenericCls"); 
            //構(gòu)造函數(shù)調(diào)用
            Object obj = helloC.getConstructor(int.class).newInstance(3);
            Method method = helloC.getMethod("getList", int.class);
            Class<?> returnType = method.getReturnType();
            System.out.println("ReturnType = " + returnType.getName());
            Parameter[] params = method.getParameters();
            for(Parameter p : params){    
                System.out.println("ParameterizedType = " + p.getParameterizedType());
                System.out.println("getModifiers = " + p.getModifiers());
                System.out.println("getName = " + p.getName());
                System.out.println("getType = " + p.getType());
            }
           //調(diào)用方法
           Object ret =  method.invoke(obj, new Object[]{2});
           System.out.println("ret = " + ret.toString());
            Method method2 = helloC.getMethod("getList", null);
            Type greturnType = method2.getGenericReturnType();
            System.out.println("getGenericReturnType = " + returnType.getName());
            if(greturnType instanceof ParameterizedType){
                ParameterizedType type = (ParameterizedType) greturnType;
                System.out.println("type = " + type.getTypeName());
                Type[] typeArguments = type.getActualTypeArguments();
                for(Type typeArgument : typeArguments){
                    Class typeArgClass = (Class) typeArgument;
                    System.out.println("typeArgClass = " + typeArgClass);
                }
            }
        }catch(ClassNotFoundException | SecurityException ex){
            ex.printStackTrace();
        }
        catch(Exception ex){
            ex.printStackTrace();
        }
    }    
}

執(zhí)行此示例,則輸出如下:

R`eturnType = java.lang.String ParameterizedType = int getModifiers = 0 getName = arg0 getType = int ret = item2 getGenericReturnType = java.lang.String type = java.util.List<java.lang.String> typeArgClass = class java.lang.String

總結(jié)

本篇文章就到這里了,希望能給你帶來幫助,也希望您能夠多多關(guān)注腳本之家的更多內(nèi)容!

相關(guān)文章

  • 數(shù)組重排序(如何將所有奇數(shù)都放在所有偶數(shù)前面)的深入分析

    數(shù)組重排序(如何將所有奇數(shù)都放在所有偶數(shù)前面)的深入分析

    本篇文章是對(duì)數(shù)組重排序(如何將所有奇數(shù)都放在所有偶數(shù)前面)的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下
    2013-06-06
  • mybatis實(shí)現(xiàn)批量插入并返回主鍵(xml和注解兩種方法)

    mybatis實(shí)現(xiàn)批量插入并返回主鍵(xml和注解兩種方法)

    這篇文章主要介紹了mybatis實(shí)現(xiàn)批量插入并返回主鍵(xml和注解兩種方法),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-12-12
  • springboot項(xiàng)目配置logback-spring.xml實(shí)現(xiàn)按日期歸檔日志的方法

    springboot項(xiàng)目配置logback-spring.xml實(shí)現(xiàn)按日期歸檔日志的方法

    本文主要介紹了springboot項(xiàng)目配置logback-spring.xml實(shí)現(xiàn)按日期歸檔日志的方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2024-08-08
  • Java中的ArrayList、LinkedList、HashSet等容器詳解

    Java中的ArrayList、LinkedList、HashSet等容器詳解

    這篇文章主要介紹了Java中的ArrayList、LinkedList、HashSet等容器詳解,集合表示一組對(duì)象,稱為其元素,有些集合允許重復(fù)元素,而另一些則不允許,有些是有序的,有些是無序的,需要的朋友可以參考下
    2023-08-08
  • IDEA報(bào)錯(cuò):無效的源發(fā)行版解決方案

    IDEA報(bào)錯(cuò):無效的源發(fā)行版解決方案

    很多小伙伴在刷新maven的時(shí)候總會(huì)報(bào) Error:java:無效的源發(fā)行版,下面這篇文章主要給大家介紹了關(guān)于IDEA報(bào)錯(cuò):無效的源發(fā)行版的解決方案,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-09-09
  • Java?toString方法使用超全講解

    Java?toString方法使用超全講解

    在Java中所有的類都有一個(gè)共同的父類Object(默認(rèn)繼承,不用加extends關(guān)鍵字),toString方法就是Object類的一個(gè)方法,用來返回該對(duì)象的字符串表示形式,下面這篇文章主要給大家介紹了關(guān)于Java?toString方法使用的相關(guān)資料,需要的朋友可以參考下
    2023-05-05
  • Springboot工具類FileCopyUtils使用教程

    Springboot工具類FileCopyUtils使用教程

    這篇文章主要介紹了Springboot內(nèi)置的工具類之FileCopyUtils的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-12-12
  • IDEA解決springboot熱部署失效問題(推薦)

    IDEA解決springboot熱部署失效問題(推薦)

    熱部署,就是在應(yīng)用正在運(yùn)行的時(shí)候升級(jí)軟件,卻不需要重新啟動(dòng)應(yīng)用。這篇文章主要介紹了IDEA解決springboot熱部署失效問題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-09-09
  • java反射簡單實(shí)例

    java反射簡單實(shí)例

    這篇文章主要介紹了java反射機(jī)制,以一個(gè)簡單實(shí)例形式分析了Java反射的原理與實(shí)現(xiàn)技巧,需要的朋友可以參考下
    2015-02-02
  • 手把手帶你實(shí)現(xiàn)第一個(gè)Mybatis程序

    手把手帶你實(shí)現(xiàn)第一個(gè)Mybatis程序

    這篇文章主要介紹了mybatis實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2021-07-07

最新評(píng)論

阳东县| 水城县| 藁城市| 长丰县| 株洲县| 柯坪县| 当雄县| 清涧县| 洪雅县| 呼伦贝尔市| 桃园县| 嘉义县| 得荣县| 鄢陵县| 五原县| 准格尔旗| 竹山县| 黑山县| 称多县| 开远市| 六盘水市| 确山县| 高平市| 罗江县| 曲沃县| 民丰县| 平潭县| 留坝县| 遂川县| 富平县| 普兰店市| 岳普湖县| 淮南市| 江川县| 吐鲁番市| 木兰县| 阿荣旗| 中牟县| 林芝县| 龙胜| 来安县|