用途:JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意方法和屬性;這種動態獲取信息以及動態調用對象方法的功能稱爲java語言的反射機制。 java
JAVA反射(放射)機制 :程序運行時,容許改變程序結構或變量類型,這種語言稱爲動態語言。從這個觀點看,Perl,Python,Ruby是動態語言,C++,Java,C#不是動態語言。可是JAVA有着一個很是突出的動態相關機制:Reflection,用在Java身上指的是咱們能夠於運行時加載、探知、使用編譯期間徹底未知的classes。換句話說,Java程序能夠加載一個運行時才得知名稱的class,獲悉其完整構造(但不包括methods定義),並生成其對象實體、或對其fields設值、或喚起其methods。 api
/**
* 反射:就是經過.class文件對象,去使用該類的成員變量,構造方法,成員方法.
*
* Person p1=new Person();
* p1.使用;
* 這個就不是反射
* @author Administrator
*
*要這樣使用就必須得到class文件對象,也就是獲得class類對象.
*獲取class類對象的方法
* 1.getClass();
* 2.數據類型的靜態屬性class
* 3.class類中的靜態方法,className要是全限定名
* public static Class<?> forName(String className)
*選擇那種方法;
* 本身隨便,開發選擇第三種,由於這種方式是一個字符串,而不是一個具體的類名,這樣咱們就能夠把字串
*配置到配置文件中
*/
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException {
//方式一
Person p1 = new Person();
Class c1 = p1.getClass();
Person p2=new Person();
Class c2 = p2.getClass();
System.out.println(p1==p2);//false
System.out.println(c1==c2);//true
//方式二
Class c3=Person.class;
//int.class;
//String.class;
System.out.println(c3==c2);//true;
//方式三,
Class c4=Class.forName("day13.Person");
System.out.println(c4==c3);
}
}
1.經過反射獲取成員變量並使用:框架
public class Reflect1 {
public static void main(String[] args) throws Exception{
//獲取字節碼對象
Class c=Class.forName("day13.Person");
/*//獲取全部成員變量
java.lang.reflect.Field[] fields=c.getDeclaredFields();
for (java.lang.reflect.Field field : fields) {
System.out.println(field);
}*/
//經過無參構造方法建立對象
Constructor cons = c.getConstructor();
Object obj=cons.newInstance();
//獲取單個成員變量
//並對其賦值
java.lang.reflect.Field addressFiled=c.getField("address");
addressFiled.set(obj, "北京");//給obj對象的addressFiled設置值.
System.out.println(obj);
}
}
Person類:ide
public class Person {
private String name;
private int age;
public String address;
//構造方法
public Person(){
}
//成員方法
Person(String name,Integer age){
this.name=name;
this.age=age;
}
public Person(String name,int age,String address){
this.name=name;
this.age=age;
this.address=address;
}
public void show(){
System.out.println("show");
}
public void method(String s){
System.out.println("method"+s);
}
public String method(String s,int i){
return s+"---"+i;
}
private void function(){
System.out.println("function");
}
2.經過反射獲取無參構造方法:函數
public class ReflectDemo {
public static void main(String[] args) throws ClassNotFoundException, SecurityException, NoSuchMethodException, IllegalArgumentException, InstantiationException, IllegalAccessException, InvocationTargetException {
//獲取字節碼對象
Class c=Class.forName("day13.Person");
//獲取構造方法
//public Constructor[] getConstructors(),獲取的是public修飾的構造方法
//public Constructor[] getDeclaredConstructors()返回全部
/*Constructor[] cons=c.getDeclaredConstructors();
for (Constructor constructor : cons) {
System.out.println(constructor);
}*/
//獲取單個構造方法
Constructor cons=c.getConstructor();
Object obj=cons.newInstance();
System.out.println(obj);
}
}
2.經過反射獲取有參構造方法:學習
public static void main(String[] args) throws Exception{
//獲取字節碼對象
Class c=Class.forName("day13.Person");
//獲取帶參構造參數
//public Constructor getConstructor(Class<?>... parameterTypes)
Constructor con = c.getConstructor(String.class,int.class,String.class);
//經過帶參構造方法對象建立對象
//public T newInstance(Object... initargs)
Object obj=con.newInstance("海燕",23,"成都");
System.out.println(obj);
}
}
3.經過放射獲取私有構造方法(加一個Declared):this
public class ReflectDemo3 {
public static void main(String[] args) throws Exception{
//獲取字節碼對象
Class c=Class.forName("day13.Person");
//獲取帶參構造函數
Constructor cons = c.getDeclaredConstructor(String.class,Integer.class);
cons.setAccessible(true);//值爲 true則指示反射的對象在使用時應該取消 Java語言訪問檢查
Object obj=cons.newInstance("海燕",23);
System.out.println(obj);
}
}
4.經過放射獲取成員變量並調用atom
package fanshe.field;
import java.lang.reflect.Field;
/*
* 獲取成員變量並調用:
*
* 1.批量的
* 1).Field[] getFields():獲取全部的"公有字段"
* 2).Field[] getDeclaredFields():獲取全部字段,包括:私有、受保護、默認、公有;
* 2.獲取單個的:
* 1).public Field getField(String fieldName):獲取某個"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):獲取某個字段(能夠是私有的)
*
* 設置字段的值:
* Field --> public void set(Object obj,Object value):
* package fanshe.field;
import java.lang.reflect.Field;
/*
* 獲取成員變量並調用:
*
* 1.批量的
* 1).Field[] getFields():獲取全部的"公有字段"
* 2).Field[] getDeclaredFields():獲取全部字段,包括:私有、受保護、默認、公有;
* 2.獲取單個的:
* 1).public Field getField(String fieldName):獲取某個"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):獲取某個字段(能夠是私有的)
*
* 設置字段的值:
* Field --> public void set(Object obj,Object value):
* 參數說明:
* 1.obj:要設置的字段所在的對象;
* 2.value:要爲字段設置的值;
*
*/
public class Fields {
public static void main(String[] args) throws Exception {
//1.獲取Class對象
Class stuClass = Class.forName("fanshe.field.Student");
//2.獲取字段
System.out.println("************獲取全部公有的字段********************");
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************獲取全部的字段(包括私有、受保護、默認的)********************");
fieldArray = stuClass.getDeclaredFields(); for(Field f : fieldArray){ System.out.println(f); } System.out.println("*************獲取公有字段**並調用***********************************"); Field f = stuClass.getField("name"); System.out.println(f); //獲取一個對象 Object obj = stuClass.getConstructor().newInstance();//產生Student對象--》Student stu = new Student(); //爲字段設置值 f.set(obj, "劉德華");//爲Student對象中的name屬性賦值--》stu.name = "劉德華" //驗證 Student stu = (Student)obj; System.out.println("驗證姓名:" + stu.name); System.out.println("**************獲取私有字段****並調用********************************"); f = stuClass.getDeclaredField("phoneNum"); System.out.println(f); f.setAccessible(true);//暴力反射,解除私有限定 f.set(obj, "18888889999"); System.out.println("驗證電話:" + stu); } }
對應的student類spa
package fanshe.field;
public class Student {
public Student(){
}
//**********字段*************//
public String name;
protected int age;
char sex;
private String phoneNum;
泛型用在編譯期,編譯事後泛型擦除(消失掉)。因此是能夠經過反射越過泛型檢查的 ,其實也就是在.class文件中沒有泛型的概念的.設計
public static void main(String[] args) throws Exception{
ArrayList<String> strList = new ArrayList<>();
strList.add("aaa");
strList.add("bbb");
// strList.add(100);
//獲取ArrayList的Class對象,反向的調用add()方法,添加數據
Class listClass = strList.getClass(); //獲得 strList 對象的字節碼 對象
//獲取add()方法
Method m = listClass.getMethod("add", Object.class);
//調用add()方法
m.invoke(strList, 100);
//遍歷集合
for(Object obj : strList){
System.out.println(obj);
}
}
啓動(Bootstrap)類加載器:java中jre中的類.
擴展(Extension)類加載器:java擴展的api類ext好像是
系統(System)類加載器:本身寫的類
https://www.2cto.com/uploadfile/Collfiles/20160126/2016012609242889.jpg