Class
類的實例表示正在運行的 Java 應用程序中的類和接口。也就是jvm中有N多的實例每一個類都有該Class對象。(包括基本數據類型)java
Class
沒有公共構造方法。Class
對象是在加載類時由 Java 虛擬機以及經過調用類加載器中的defineClass
方法自動構造的。也就是這不須要咱們本身去處理建立,JVM已經幫咱們建立好了。框架
Class類中有64個方法,具體用到哪一個再詳細介紹哪一個。jvm
3.2任何的數據類型(包括基本數據類型)都有一個「靜態的」calss屬性ide
3.3經過Class類的靜態方法: Class.forName(String className) //className是全路徑名——包名+類名,可是並非磁盤的絕對路徑 (經常使用)測試
public void f1() throws ClassNotFoundException { //獲取class對象
/* * 1.經過對象來獲取字節碼對象 * 缺點:我對象都有了。。。還要字節碼對象作啥子*/ Student student=new Student(); //這樣一建立 其實建立了2個對象 student對象 以及Student類對應的class對象
Class stuClass1=student.getClass(); /* * 2.經過每一個類型都有的「靜態的」class屬性來獲取 * 缺點:依賴性太強,得導入相應的類的包;不然編譯不過*/ Class stuClass2=Student.class; /* * 經常使用,須要掌握 * Class forName(String className) 注意:全限類名*/ Class stuClass3=Class.forName("com.kylin.FanShe.Student"); System.out.println(stuClass1==stuClass2); System.out.println(stuClass1==stuClass3); System.out.println(stuClass2==stuClass3); //結果3個都是true,說明——一個類只有一個class對象
}
2.獲取一個構造器(若是是無參構造器,那麼參數寫null或者不寫)
2.1獲取單個 共有的構造器
public Constructor getConstructor(Class ... paramterTypes) ;//獲取單個的「公有的」構造方法(參數是構造器參數的類型;注意是構造器參數的類型!)
2.2.獲取單個任何類型的構造器
public Constructor getDeclaredConstructor(Class... parameterTypes):獲取"某個構造方法"能夠是私有的,或受保護、默認、公有
3.經過構造方法對象來建立對象
Object newInstance(構造器的參數) //構造方法的一個方法,用於建立對象,返回Object類型 須要本身手動的類型轉換一下
Student.java
package com.kylin.FanShe; public class Student { private String name; //姓名 private String sex; //性別 private String id; //學號 private int age; //年齡 //4種訪問類型的構造器 包訪問類型 共有 保護 私有 Student(){ System.out.println("包訪問類型的構造器"); } //共有 public Student(String name){ this.name=name; System.out.println("共有訪問類型的構造器,且名字爲:"+name); } public Student(String id, int age){ this.id=id; this.age=age; System.out.println("共有的構造器,id,年齡"+id+" "+age); } //保護 protected Student(String name,String sex){ this.name=name; this.sex=sex; System.out.println("保護類型的構造器,且名字爲:"+name+"性別:"+sex); } //私有 private Student(String name,String id,String sex){ this.name=name; this.id=id; this.sex=sex; System.out.println("私有的構造器:"+name+" "+id+" "+sex); } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getId() { return id; } public void setId(String id) { this.id = id; } public int getAge() { return age; } public void setAge(int age) { this.age = age; } }
獲取構造方法代碼: (一開始引入了:import java.lang.reflect.Constructor)
public static void main(String []args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { // 獲取class對象 Class clazz=Class.forName("com.kylin.FanShe.Student"); //1.1獲取全部的公有的構造器 Constructor []constructors=clazz.getConstructors(); for (Constructor constructor:constructors){ System.out.println(constructor); } /* * 結果: * public com.kylin.FanShe.Student(java.lang.String,int) public com.kylin.FanShe.Student(java.lang.String) * */ System.out.println("-----------------------------美麗的分割線-------------------------------"); //1.2獲取全部任何類型的構造方法 Constructor []allConstructors=clazz.getDeclaredConstructors(); for (Constructor constructor:allConstructors){ System.out.println(constructor); } /* * 結果: * private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String) protected com.kylin.FanShe.Student(java.lang.String,java.lang.String) public com.kylin.FanShe.Student(java.lang.String,int) public com.kylin.FanShe.Student(java.lang.String) com.kylin.FanShe.Student()*/ System.out.println("-----------------------------美麗的分割線-------------------------------"); //2.1獲取某個公有的 構造器 Constructor myPubConstructor=clazz.getConstructor(String.class); //參數是:構造器參數的類型 System.out.println(myPubConstructor); // 輸出:public com.kylin.FanShe.Student(java.lang.String) System.out.println("-----------------------------美麗的分割線-------------------------------"); //2.2獲取某個任何類型的構造器 Constructor myEveConstructor=clazz.getDeclaredConstructor(String.class,String.class,String.class); System.out.println(myEveConstructor); // 輸出:private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String) //經過構造方法來建立對象 Student student= (Student) myPubConstructor.newInstance("name"); System.out.println(student.getName()); // 這樣會拋出異常,由於一個私有的構造器不能被用來建立對象 因此須要設置訪問權限 // Student student1= (Student) myEveConstructor.newInstance("1","22","333"); // System.out.println(student1.getName()+" "+student1.getId()+" "+student1.getSex()); myEveConstructor.setAccessible(true);//暴力訪問 Student student1= (Student) myEveConstructor.newInstance("111","222","333"); System.out.println(student1.getName()+" "+student1.getSex()+" "+student1.getId()); }
輸出結果:this
public com.kylin.FanShe.Student(java.lang.String,int) public com.kylin.FanShe.Student(java.lang.String) -----------------------------美麗的分割線------------------------------- private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String) protected com.kylin.FanShe.Student(java.lang.String,java.lang.String) public com.kylin.FanShe.Student(java.lang.String,int) public com.kylin.FanShe.Student(java.lang.String) com.kylin.FanShe.Student() -----------------------------美麗的分割線------------------------------- public com.kylin.FanShe.Student(java.lang.String) -----------------------------美麗的分割線------------------------------- private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String) 共有訪問類型的構造器,且名字爲:name name 私有的構造器:111 222 333 111 333 222
teacher.javaspa
package com.kylin.FanShe; public class Teacher { public String name; public String name1; String school; protected String sex; private int age; public Teacher(){ } @Override public String toString(){ return "Teacher[name="+name+",school=" +school+ ",sex="+sex+",age="+age+",name1="+name1; } }
測試獲取成員變量而且調用.net
package com.kylin.FanShe; import org.junit.Test; import java.lang.reflect.Field; import java.lang.reflect.InvocationTargetException; //獲取成員變量 public class GetFiled { /* * 獲取成員變量並調用: * * 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 static void main(String []args) throws ClassNotFoundException, NoSuchFieldException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException { //獲取class對象 Class clazz=Class.forName("com.kylin.FanShe.Teacher"); //獲取全部的共有的屬性 Field []fields=clazz.getFields(); for (Field field:fields){ System.out.println(field); } System.out.println("-----------------------------美麗分割線-------------------------"); //獲取全部的屬性 (任何訪問類型) Field []allFields=clazz.getDeclaredFields(); for (Field field:allFields){ System.out.println(field); //這也是一個對象來的 } System.out.println("-----------------------------美麗分割線-------------------------"); //獲取指定的共有屬性而且賦值給對象 Field nameField=clazz.getField("name"); System.out.println(nameField); Teacher teacher= (Teacher) clazz.getConstructor(null).newInstance(); nameField.set(teacher,"蘇桃"); System.out.println(teacher); System.out.println("-----------------------------美麗分割線-------------------------"); //獲取指定的任何類型(這裏獲取私有來測試)的屬性 而且賦值給對象 Field priAgeField=clazz.getDeclaredField("age"); //女人的年齡是祕密嘛 System.out.println(priAgeField); //私有的須要設置權限 這裏是暴力訪問 priAgeField.setAccessible(true); priAgeField.set(teacher,20); System.out.println(teacher); } }
輸出:3d
public java.lang.String com.kylin.FanShe.Teacher.name public java.lang.String com.kylin.FanShe.Teacher.name1 -----------------------------美麗分割線------------------------- public java.lang.String com.kylin.FanShe.Teacher.name public java.lang.String com.kylin.FanShe.Teacher.name1 java.lang.String com.kylin.FanShe.Teacher.school protected java.lang.String com.kylin.FanShe.Teacher.sex private int com.kylin.FanShe.Teacher.age -----------------------------美麗分割線------------------------- public java.lang.String com.kylin.FanShe.Teacher.name Teacher[name=蘇桃,school=null,sex=null,age=0,name1=null -----------------------------美麗分割線------------------------- private int com.kylin.FanShe.Teacher.age Teacher[name=蘇桃,school=null,sex=null,age=20,name1=null
people.javacode
package com.kylin.FanShe; public class People { public void show1(String s){ System.out.println("調用了:公有的,String參數的show1(): s = " + s); } protected void show2(){ System.out.println("調用了:受保護的,無參的show2()"); } void show3(){ System.out.println("調用了:默認的,無參的show3()"); } private String show4(int age) { System.out.println("調用了,私有的,而且有返回值的,int參數的show4(): age = " + age); return "abcd"; } }
獲取成員方法而且調用
/* 獲取成員方法並調用 * 1.批量的: * public Method[] getMethods():獲取全部"公有方法";(包含了父類的方法也包含Object類) * public Method[] getDeclaredMethods():獲取全部的成員方法,包括私有的(不包括繼承的) 2.獲取單個的: * public Method getMethod(String name,Class<?>... parameterTypes): * 參數: * name : 方法名; * Class ... : 形參的Class類型對象 public Method getDeclaredMethod(String name,Class<?>... parameterTypes) * 調用方法: * Method --> public Object invoke(Object obj,Object... args): * 參數說明: * obj : 要調用方法的對象,這個對象必定要是和方法同一類/或者子類也應該能夠的; * args:調用方式時所傳遞的實參; ): */ public static void main(String[] args) throws Exception { //1.獲取Class對象 Class clazz = Class.forName("com.kylin.FanShe.People"); //2.獲取全部公有方法 System.out.println("***************獲取全部的」公有「方法*******************"); Method[] methodArray = clazz.getMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println("***************獲取全部的方法,包括私有的*******************"); methodArray = clazz.getDeclaredMethods(); for (Method m : methodArray) { System.out.println(m); } System.out.println("***************獲取公有的show1()方法*******************"); Method pubMethod = clazz.getMethod("show1", String.class); System.out.println(pubMethod); //實例化一個Student對象 People people= (People) clazz.getConstructor().newInstance(); pubMethod.invoke(people,"劉德華"); //方法對象被調用執行,則輸出了那句話 System.out.println("***************獲取私有的show4()方法******************"); Method priMethod = clazz.getDeclaredMethod("show4", int.class); System.out.println(priMethod); priMethod.setAccessible(true);//解除私有限定 System.out.println("11111111111111111111111"); //拋出異常 多是得該類的對象才能夠調用 // Object object=new Object(); People people1= (People) clazz.getConstructor().newInstance(); priMethod.invoke(people1, 20);//須要兩個參數,一個是要調用的對象(獲取有反射),一個是實參 // System.out.println("返回值:" + result); }
反射能夠獲取到一個類的全部的東西——靜態的非靜態的,私有的公有的……只要是在類中的,或者繼承於父類的東西,均可以被獲取成一個對象,而後進行調用……固然也能夠獲取main方法等等,這裏主要介紹了經過類的字節碼對象獲取構造方法,成員變量,方法等……反射同時也是不少框架實現的基礎,要好好琢磨……