歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
您现在的位置: Linux教程網 >> UnixLinux >  >> Linux編程 >> Linux編程

Java面向對象編程之反射

一 java中類的加載

1 jvm使用一個類的時候,是通過一個ClassLoader,把類加載到內存中,獲得該類的Class對象;

2 ClassLoader加載一個類的時候,會檢查上級的ClassLoader是否沒有加載過該類,若已加載過,不再加載;

二 程序塊

靜態程序塊,在類加載的時候就會被執行,A加載的時候,會將static程序塊部分執行;

若去掉static,變成非靜態程序塊,在A類加載的時候,非靜態程序塊不會被執行,只有創建實例的時候才會被執行,創建一個實例執行一次;

package com.ob.temp;

public class User {
 public static void main(String[] args) throws ClassNotFoundException {
  Class.forName("com.ob.temp.A");
 
 
 }
}

class A{
 static{
  System.out.println("A已加載");
 }
 
 String name;
 int age;
 
 A(){
 
 }
 A(String name,int age){
  this.name=name;
  this.age=age;
 }
 
 void say(String name,int age){
  System.out.println(name+":+age");
 }
 void m1(){
  System.out.println("in m1");
 }
}

二 反射(java.lang.reflect)

1 反射:反射是獲取運行的java類的全部信息,包括構造方法,成員變量和方法等;獲取的方式是通過,該類對應的Class類對象的方法獲取的;

2 創建Class類對象三種方式:

Class.forName("要加載類的完整類路徑");

類名.class;

對象的引用.getClass();

Class c1=Class.forName("com.ob.temp.A");
  Class c2=A.class;
  A a=new A();
  A a1=new A();
  Class c3=a.getClass();
  System.out.println(c1==c2);
  System.out.println(c1==c3);

會返回兩個true;

3 通過一個類的Class對象創建實例

Class c1=Class.forName("com.ob.temp.A");
  A a=(A) c1.newInstance();
  a.m1();

這裡是通過Class對象的newInstance()方法返回的;

4 訪問構造方法:

  Class c1=Class.forName("com.ob.temp.A");
  Constructor[] cs=c1.getDeclaredConstructors();
  for(Constructor c:cs){
   System.out.println(c.getName());
  }
  Constructor c=c1.getDeclaredConstructor(String.class,int.class);
  A a=(A) c.newInstance("zhangsan",5);
  System.out.println(a.name+":"+a.age);
 }

可以訪問所有的構造方法,也可以訪問指定參數的構造方法,構造方法對象 調用newInstance方法返回實例,可以含有參數;

5 訪問成員變量:

 Class c1=Class.forName("com.ob.temp.A");
  Field[] fs=c1.getDeclaredFields();
  for(Field f:fs){
   System.out.println(f.getName());
  }
  Field fname=c1.getDeclaredField("name");
  System.out.println(fname.getName());

類似於構造方法的訪問,可以返回變量數組,也可以返回指定的變量;

  Class c1=Class.forName("com.ob.temp.A");
  A a=(A) c1.newInstance();
  Field[] fs=c1.getDeclaredFields();
  for(Field f:fs){
   System.out.println(f.getName()+"的初始值是:"+f.get(a));
   if(f.getType().equals(String.class)){
    f.set(a, "zhangsan");
   }
   if(f.getType().equals(int.class)){
    f.setInt(a, 20);
   }
   System.out.println(f.getName()+"修改後的值是:"+f.get(a));
  }

成員變量的Class對象getType()返回類型對應的Class對象,成員變量的Class對象get(Object obj)返回obj的對象對應的變量值,修改成員變量的值,用setXXX(Object obj,值)XXX根據變量類型決定;

6 訪問方法:

Class c1=Class.forName("com.ob.temp.A");
  A a=(A) c1.newInstance();
  Method[] methods=c1.getDeclaredMethods();
  for(Method m:methods){
   System.out.println(m.getName());
  }
 
  Method me=c1.getDeclaredMethod("say", String.class,int.class);
  System.out.println(me.getName());

既可以得到方法數組,也可以訪問指定名稱和參數的方法;

 Class c1=Class.forName("com.ob.temp.A");
  A a=(A) c1.newInstance(); 
  Method me=c1.getDeclaredMethod("say", String.class,int.class);
  me.invoke(a, "zhang",20);

方法對應的類類對象調用invoke("實例對象",參數列表沒有參數可以不寫);

Copyright © Linux教程網 All Rights Reserved