類加載器、反射

當程序要使用某個類時,若是該類還未被加載到內存中,則系統會經過加載,鏈接,初始化三步來實現對這個類進行初始化。java

加載:指將class文件讀入內存,併爲之建立一個class對象。數組

鏈接:驗證  是否有正確的內部結構,並和其它類協調一致。準備  負責爲類的靜態成員分配內存,並設置默認初始化值。 解析  將類的二進制數據中的符號引用替換爲直接引用。oracle

初始化:初始化步驟。this

Bootstrap ClassLoader 根類加載器spa

也被稱爲引導類加載器,負責Java核心類的加載code

Extension ClassLoader 擴展類加載器對象

負責JRE的擴展目錄中jar包的加載。blog

System ClassLoader 系統類加載器內存

負責在JVM啓動時加載來自java命令的class文件,以及classpath環境變量所指定的jar包和類路徑。get

 

反射:JAVA反射機制是在運行狀態中,對於任意一個類,都可以知道這個類的全部屬性和方法;對於任意一個對象,都可以調用它的任意一個方法和屬性;這種動態獲取的信息以及動態調用對象的方法的功能稱爲java語言的反射機制。

Class類:

獲取Class對象的三種方式:

 

public static void main(String[] args) throws ClassNotFoundException {
  //獲取字節碼文件對象
  //1.經過對象獲取
  Class c1=new Person().getClass();
  System.out.println(c1);
  //2.經過類名獲取
  Class c2=Person.class;
  System.out.println(c2);
  //System.out.println(c1==c2);//true
  //3.經過class類的靜態方法獲取
  Class c3=Class.forName("com.oracle.demo01.Person");
  System.out.println(c3);
}

Person類:

public class Person {
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    private String name;
    public int age;
    public Person(){
        System.out.println("public Person()");
    }
    public Person(String name){
        this.name=name;
        System.out.println("public Person(String name)");
    }
    private Person(int age){
        this.age=age;
        System.out.println("private Person(int age)");
    }
    static{
        System.out.println("靜態代碼塊");
    }
    public void eat(){
        System.out.println("public void eat()");
    }
    public void sleep(String name,int age){
        System.out.println("public void sleep(String name,int age)");
    }
    public void sleep(String name){
        System.out.println("public void sleep(String name)");
    }
    private void smoke(int age){
        System.out.println("private void smoke(int age)");
    }
}

經過反射方式,獲取構造方法,建立對象:

public static void method() throws ClassNotFoundException{
  //獲取字節碼文件對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取全部公共的構造方法對象數組
  //Constructor[] cons=c.getConstructors();
  //獲取全部構造方法
  Constructor[] cons=c.getDeclaredConstructors();
  for(Constructor con:cons){
    System.out.println(con);
  }
}

public static void method2() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //獲取字節碼對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取空參構造方法對象
  Constructor con=c.getConstructor();
  //調用構造方法建立對象
  Object obj=con.newInstance();
  //向下轉型
  Person p=(Person)obj;
  p.eat();
}
public static void method3() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //獲取字節碼對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取有參構造方法對象
  Constructor con=c.getConstructor(String.class);
  //調用構造方法建立對象
  Object obj=con.newInstance("張三");
  //向下轉型
  Person p=(Person)obj;
  p.eat();
}

經過反射方式,獲取私有構造方法,建立對象:

public static void method4() throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
  //獲取字節碼對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取有參構造方法對象
  Constructor con=c.getDeclaredConstructor(int.class);
  //暴力反射:取消java語言檢測訪問
  con.setAccessible(true);
  //調用構造方法建立對象
  Object obj=con.newInstance(18);
  //向下轉型
  Person p=(Person)obj;
  p.eat();
}

經過反射,建立對象,獲取指定的成員變量,進行賦值與獲取值:

public static void method01() throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException{
  //獲取字節碼文件對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取公共的成員變量
  Field f=c.getField("age");
  //快速建立對象
  Object obj=c.newInstance();
  //給對象的成員變量賦值
  f.set(obj, 18);
  System.out.println(obj);
}
public static void method02() throws NoSuchFieldException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException{
  //獲取字節碼文件對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取公共的成員變量
  Field f=c.getDeclaredField("name");
  //暴力反射
  f.setAccessible(true);
  //快速建立對象
  Object obj=c.newInstance();
  //給對象的成員變量賦值
  f.set(obj, "你好");
  System.out.println(f);
}

經過反射獲取成員方法並使用:

 

public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  //獲取字節碼文件對象
  Class c=Class.forName("com.oracle.demo01.Person");
  //獲取公共有參成員方法
  Method method=c.getMethod("sleep", String.class,int.class);
  //System.out.println(method);
  //快速建立對象
  Object obj=c.newInstance();
  //調用方法
  method.invoke(obj, "張三",18);
}

泛型擦除:

public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
  //泛型擦除
  ArrayList<String> arr=new ArrayList<String>();
  //反射
  Class c=arr.getClass();
  Method method=c.getMethod("add", Object.class);
  //調用
  method.invoke(arr, 123);
  System.out.println(arr);
}

相關文章
相關標籤/搜索