天天看點

java反射機制 路徑_Java反射機制

.反射的概述

JAVA反射機制是在運作狀态中,對于任意一個類,都能夠知道這個類的所有屬性和方法;對于任意一個對象,都能夠調用它的任意一個方法和屬性;這種動态擷取的資訊以及動态調用對象的方法的功能稱為java語言的反射機制。

要想解剖一個類,必須先要擷取到該類的位元組碼檔案對象。而解剖使用的就是Class類中的方法.是以先要擷取到每一個位元組碼檔案對應的Class類型的對象。

反射是java語言中的一種機制,通過這種機制可以動态的執行個體化對象、讀寫屬性、調用方法

.反射強大之處:

反射機制它沒有局限性,可以知道任意一個類的所有屬性以及方法,對于任意一個對象,都能夠調用它的任意一個方法和屬性。

例:

* 為什麼jdbc連接配接要使用Class.forName("com.jdbc.mysql.Driver");*不管是mysql的驅動 Driver還是Oracle的驅動或者其他驅動;

* 它都需要去實作jdbc的一個驅動接口;* com.jdbc.mysql.Driver extendsjava.sql.Driver* java.sql.Driver d= Class.forName("com.jdbc.mysql.Driver")*

*例:*

* xxx

* com.xxx.xxxServlet

*

*...* com.xxx.xxxServlet extendshttpServlet*通過模組化我們就可以擷取到com.xxx.xxxServlet這個路徑* Class> clz=Class.forName("com.xxx.xxxServlet");* httpServlet httpservlet = clz.newInstanse();//擷取到類對象就什麼都可以幹了

一切反射相關的代碼都從獲得類(java.lang.Class)對象開始

1 Class.forName(完整類名)              jdbc、自定義mvc架構用到

2 類名.class                                     可用作通用的查詢

3 對象.getClass()                             通用增删改可用

注1:ClassNotFoundException(類名錯|少jar包)

注2:同一類的、類對象隻會建立一個

測試類資訊:

packagecom.yuan.reflect;public classStudent {privateString sid;privateString sname;publicInteger age;static{

System.out.println("加載進jvm中!");

}publicStudent() {super();

System.out.println("調用無參構造方法建立了一個學生對象");

}publicStudent(String sid) {super();this.sid =sid;

System.out.println("調用帶一個參數的構造方法建立了一個學生對象");

}publicStudent(String sid, String sname) {super();this.sid =sid;this.sname =sname;

System.out.println("調用兩個參數的構造方法建立了一個學生對象");

}

@SuppressWarnings("unused")privateStudent(Integer age) {

System.out.println("調用Student類私有的構造方法建立了一個學生對象");this.age =age;

}publicString getSid() {returnsid;

}public voidsetSid(String sid) {this.sid =sid;

}publicString getSname() {returnsname;

}public voidsetSname(String sname) {this.sname =sname;

}public voidhello() {

System.out.println("你好!我是" + this.sname);

}public voidhello(String name) {

System.out.println(name+ "你好!我是" + this.sname);

}

@SuppressWarnings("unused")privateInteger add(Integer a, Integer b) {return new Integer(a.intValue() +b.intValue());

}

@OverridepublicString toString() {return "Student [sid=" + sid + ", sname=" + sname + ", age=" + age + "]";

}

}

1、Class.forName("類的全路徑名");

Class clz = Class.forName("com.yuan.reflect.Student");

System.out.println(clz);

結果:

class com.yuan.reflect.Student

2、類名.class

Class clz=Student.class;

System.out.println(clz);

結果:

class com.yuan.reflect.Student

3、類(Class類類的類對象) 執行個體.getClass()      通用增删改可用

Student stu=newStudent();

Class clz=stu.getClass();

System.out.println(clz);

結果:

class com.yuan.reflect.Student

.反射的三大作用

1. 執行個體化對象          .newInstance();

代碼:

packagecom.yuan.reflect;importjava.lang.reflect.Constructor;

public classDemo2 {public static void main(String[] args) throwsException {

Class clz= Student.class;//1、反射調用無參構造方法建立了一個學生對象

// Student stu=(Student)clz.newInstance();//2、調用一個有參構造方法建立一個學生對象//拿到構造器類//Constructor con = clz.getConstructor(String.class);//傳回一個構造器// //通過構造器執行個體化對象//Student stu = (Student)con.newInstance("s007");//System.out.println(stu);//3、調用兩個有參構造方法建立一個學生對象//拿到構造器類//Constructor con = clz.getConstructor(String.class,String.class);//傳回一個構造器// //通過構造器執行個體化對象//Student stu = (Student)con.newInstance("s007","zhangsna");//System.out.println(stu);//4、調用Student類私有的構造方法建立了一個學生對象//#java.lang.NoSuchMethodException: 未找到該方法(因為方法私有化是以不可被調用)//# getConstructor 這個方法隻能尋找到public(公開的)修飾的構造器//Constructor con = clz.getConstructor(Integer.class);//# getDeclaredConstructor 此方法可以尋找到任何修飾符修飾的構造器//Constructor con = clz.getDeclaredConstructor(Integer.class);//# 設定私有方法可被通路//con.setAccessible(true);// //通過構造器執行個體化對象//Student stu = (Student)con.newInstance(17);//System.out.println(stu);

}

}

結果1:

java反射機制 路徑_Java反射機制

結果2:

java反射機制 路徑_Java反射機制

結果3:

java反射機制 路徑_Java反射機制

結果4:

java反射機制 路徑_Java反射機制

出現錯誤1:java.lang.NoSuchMethodException ,說明你用的是getConstructor()方法,換成getDeclaredConstructor();

出現錯誤2: java.lang.IllegalAccessException    沒有設定私有可通路,加 .setAccessible(true);

這兩種都是針對于擷取私有方法時找不到方法會出現的錯誤

2. 動态調用方法      .invoke

public static void main(String[] args) throwsException {

Student stu=newStudent();//stu.hello();//普通調用方法

Class clz=stu.getClass();//調用無參方法//Method m = clz.getDeclaredMethod("hello");//m.invoke(stu);//調用帶參方法

Method m = clz.getDeclaredMethod("add",Integer.class,Integer.class);

m.setAccessible(true);//invoke 如果反射動态調用的方法是被void所修飾,他傳回的就是null//如果反射動态調用的方法不是被void所修飾,那麼傳回的就是被調用的方法的傳回值

Object o=m.invoke(stu,20,5);

System.out.println(o);

}

結果:

java反射機制 路徑_Java反射機制

3 .讀寫屬性             set/get

packagecom.yuan.reflect;importjava.lang.reflect.Field;

public classDemo4 {public static void main(String[] args) throwsException{

Student stu=new Student("s008","lili");//stu.setSid("s004");

stu.age=22;//System.out.println(stu);

// 指派//反射處理的是一類的問題,在處理多個屬性指派或取值的時候,使用反射可以減省很多代碼//處理私有(private)屬性時 需要設定它為可被通路: setAccessible(true);

Class clz=stu.getClass();

Field field= clz.getDeclaredField("sid");//被指派的屬性

field.setAccessible(true);//設定私有可被通路

field.set(stu, "s02");//屬性指派

System.out.println(stu);

System.out.println(field.get(stu));

//取值//Field[] fields = clz.getDeclaredFields();//for (Field field : fields) {//field.setAccessible(true);//System.out.println(field.getName()+"--"+field.get(stu));//}

}

}

指派結果:

加載進jvm中!

調用兩個參數的構造方法建立了一個學生對象

Student [sid=s02, sname=lili, age=22]

s02

取值結果:

加載進jvm中!

調用兩個參數的構造方法建立了一個學生對象

sid--s008

sname--lili

age--22

.通路修飾符    getModifiers()

測試類資訊:

public classStudent {privateString sid;privateString sname;publicInteger age;

}

測試代碼:

public static voidmain(String[] args) {

Class clz=Student.class;

Field[] fields=clz.getDeclaredFields();for(Field field : fields) {

System.out.println("-->");

System.out.println(Modifier.toString(field.getModifiers()));

}

}

輸出結果:

-->private

-->private

-->public

謝謝觀看!^-^