日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
JAVA的反射機(jī)制大總結(jié)

JAVA反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動態(tài)獲取的信息以及動態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制,本篇文章為大家詳細(xì)講解一下JAVA的反射機(jī)制。

創(chuàng)新互聯(lián)專注于鹽都企業(yè)網(wǎng)站建設(shè),成都響應(yīng)式網(wǎng)站建設(shè)公司,商城開發(fā)。鹽都網(wǎng)站建設(shè)公司,為鹽都等地區(qū)提供建站服務(wù)。全流程按需開發(fā)網(wǎng)站,專業(yè)設(shè)計(jì),全程項(xiàng)目跟蹤,創(chuàng)新互聯(lián)專業(yè)和態(tài)度為您提供的服務(wù)

一、Class類

在程序運(yùn)行期間,Java運(yùn)行時(shí)系統(tǒng)始終對所有的對象維護(hù)一個(gè)被稱為運(yùn)行時(shí)的類型標(biāo)識。這個(gè)信息跟蹤著每個(gè)對象所屬的類。虛擬機(jī)利用運(yùn)行時(shí)類型信息選擇相應(yīng)的方法執(zhí)行??梢酝ㄟ^專門的Java類訪問這些信息。保存這些信息的類被稱為Class。

創(chuàng)建Class類對象的三種方法:

1. 通過getClass方法

Object中的getClass方法將返回一個(gè)Class類型的實(shí)例。

class Person {
  //...
}

Person p = new Person();
Class c = p.getClass();

2. forName方法

可以通過靜態(tài)方法forName獲得類名對應(yīng)的Class對象。

String className = "java.util.Date";
Class c = Class.forName(className);

如果需要在運(yùn)行過程中需要改變類名,就可以使用這種方法。當(dāng)然,字符串className必須是一種類名或接口(包括包名),否則會出現(xiàn)異常。

3. T.class

Class c1 = Date.class;
Class c2 = int.class;
Class c3 = Double[].class;

T表示任意的Java類型。通過T.class獲取匹配的類對象。

注意:一個(gè)Class對象實(shí)際表示一種類型,而這種類型未必是一種類。

虛擬機(jī)為每個(gè)類型管理一個(gè)Class對象。因此可以用==運(yùn)算符來實(shí)現(xiàn)兩個(gè)類對象的比較

if (p.getClass() == Person.class) {...}

newInstance方法

通過newInstance方法可以創(chuàng)建一個(gè)類的實(shí)例。

Person person = p.getClass().newInstance();

創(chuàng)建了一個(gè)與p具有相同類類型的實(shí)例。newInstance調(diào)用默認(rèn)的構(gòu)造器初始化創(chuàng)建的對象。如果這個(gè)類沒有默認(rèn)的構(gòu)造器,就會拋出異常。

二、利用反射解析類結(jié)構(gòu)

獲取包名+類名(包括父類名)

package com.xiaoxiaoyihan.reflection;

class Person {
   //...
}

class Student extends Person{

}

public class ReflectionDemo1 {
   public static void main(String[] args) {
       Student s = new Student();
       Class cl = s.getClass();
       Class superCl = cl.getSuperclass();
       System.out.println("獲取類名:" + cl.getName());
       System.out.println("獲取父類名:" + superCl.getName());
   }
}

【運(yùn)行結(jié)果】: 獲取類名:com.xiaoxiaoyihan.reflection.Student 獲取父類名:com.xiaoxiaoyihan.reflection.Person

說明:如果類在一個(gè)包中,包的名字也作為類名的一部分。

一點(diǎn)擴(kuò)展:

首先看一個(gè)例子:

class Person {
   private String name = "蕭蕭弈寒";
   // 省略setter和getter
}
class Animal {
   private String name = "paqi";
   // 省略setter和getter
}

Person p;
Animal a;
Class cPerson = p.getClass();
Class cAnimal = a.getClass();
// cPerson.getName()獲取的是類名、p.getName()是Person實(shí)例的name屬性值
System.out.println(cPerson.getName() + "" + p.getName());
System.out.println(cAnimal.getName() + "" + p.getName());

【運(yùn)行結(jié)果】: com.xxyh.reflec.Person蕭蕭弈寒 com.xxyh.reflec.Animalpaqi

由此說明,一個(gè)Person對象p表示一個(gè)特定人的屬性,一個(gè)Animal對象a表示一個(gè)特定動物的屬性,一個(gè)Class對象表示一個(gè)特定類(Person或Animal)的屬性。從這點(diǎn)看,Class的實(shí)例是一種對象。

解析構(gòu)造函數(shù)(Constructor)

Class類中的getConstructors方法將返回公共構(gòu)造器數(shù)組。Class類中的getDeclaredConstructors將返回類中聲明的構(gòu)造器數(shù)組。

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Constructor;
class Person {
   private String name;
   private int age;

   private Person() {}

   protected Person(String name) {
       this.name = name;
   }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
   }
}
public class ReflectionDemo1 {
   public static void main(String[] args) throws ClassNotFoundException {
       Class cl = Class.forName("com.xiaoxiaoyihan.reflection.Person");  // 直接拋出異常以簡化代碼

       Constructor[] constructors = cl.getDeclaredConstructors();
       //Constructor[] constructors = cl.getConstructors();
       for (Constructor c :constructors) {
           System.out.println(c);
       }
   }
}

【運(yùn)行結(jié)果】:

private com.xiaoxiaoyihan.reflection.Person() protected com.xiaoxiaoyihan.reflection.Person(java.lang.String) public com.xiaoxiaoyihan.reflection.Person(java.lang.String,int)

// public com.xiaoxiaoyihan.reflection.Person(java.lang.String,int)// 本部分為運(yùn)行g(shù)etConstructors方法輸出結(jié)果

對結(jié)果加以分析,會發(fā)現(xiàn)通過System.out.println(c);直接打印的構(gòu)造函數(shù)是由幾部分組成的,其中包括了修飾符(public/protected/private)、**類名*以及*構(gòu)造函數(shù)的參數(shù),那么,這些部分是如何獲取的呢?

Modifier類中包含靜態(tài)方法getModifiers方法,它返回一個(gè)整數(shù)i,用不同的數(shù)值表示public、static、final這樣的修飾符。Modifier中的靜態(tài)方法toString(i)返回對應(yīng)的修飾符。Constructor類中包含由靜態(tài)方法getParameterTypes,它返回一個(gè)描述參數(shù)類型的Class對象數(shù)組。

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Modifier;

class Person {
   private String name;
   private int age;

   private Person() {}

   protected Person(String name) {
       this.name = name;
   }

   public Person(String name, int age) {
       this.name = name;
       this.age = age;
   }
}
public class ReflectionDemo1 {
   public static void main(String[] args) throws ClassNotFoundException {
       Class cl = Person.class;

       Constructor[] constructors = cl.getDeclaredConstructors();
       for (Constructor c :constructors) {
           // 獲取包名和類名
           String name = c.getName();

           // 獲取修飾符
           String modifiers = Modifier.toString(c.getModifiers());
           if (modifiers.length() > 0) {   //如果有修飾符
               System.out.print(modifiers + " ");
           }

           System.out.print(name + "(");

           // 獲取構(gòu)造函數(shù)的參數(shù)類型
           Class[] paramTypes = c.getParameterTypes();

           for (int i = 0; i if (i > 0) {    // 如果不止一個(gè)參數(shù),使用","將參數(shù)類型分割
                   System.out.print(",");
               }
               System.out.print(paramTypes[i].getName());
           }
           System.out.println(");");
       }

   }
}

【運(yùn)行結(jié)果】:

private com.xiaoxiaoyihan.reflection.Person(); protected com.xiaoxiaoyihan.reflection.Person(java.lang.String); public com.xiaoxiaoyihan.reflection.Person(java.lang.String,int);

解析方法(Method)

Class類中的getMethods將返回方法的數(shù)組,其中包括本類的所有方法、從接口實(shí)現(xiàn)的方法、父類的公共(public)方法、父類的父類的公共方法……一直延伸到Object的公共方法getDeclaredMethods方法將返回本類聲明的方法、從接口實(shí)現(xiàn)的方法

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;


class Person/* extends Object */ {
   private void privateMethodPerson() {
       //...
   }

   protected void protectedMethodPerson() {
       // ...
   }

   public void publicMethodPerson() {
       //...
   }
}

interface Smoke {
   void smoking();
}

class Student extends Person implements Smoke{
   @Override
   public void smoking() {
       // ...
   }

   private void privateMethodStudent() {
       //...
   }

   protected void protectedMethodStudent() {
       // ...
   }

   public void publicMethodStudent() {
       //...
   }
}


public class ReflectionDemo1 {
   public static void main(String[] args) {
       Student s = new Student();
       Class cl = s.getClass();
       Method[] methods = cl.getDeclaredMethods();
//        Method[] methods = cl.getMethods();

       for (Method m : methods) {
           System.out.println(m);
       }
   }
}

【運(yùn)行結(jié)果】:

public void com.xiaoxiaoyihan.reflection.Student.smoking() protected void com.xiaoxiaoyihan.reflection.Student.protectedMethodStudent() private void com.xiaoxiaoyihan.reflection.Student.privateMethodStudent() public void com.xiaoxiaoyihan.reflection.Student.publicMethodStudent()

上面的例子故意給出一種繼承結(jié)構(gòu),是為了查看getMethods的結(jié)果,在此就不給出結(jié)果了。注意Person默認(rèn)繼承了Object類。順便說一句,筆者(非科班自學(xué)菜鳥)曾在面試的時(shí)候被問到Object中有哪些方法,估計(jì)他是想問有哪些常用方法吧,我沒答全~2333,不知道讀者您能一眼看出結(jié)果嗎??。

類似地,我們看到上面的System.out.println(m);打印出方法由修飾符返回值**、*類名、方法名以及參數(shù)*組成。那么這些部分是如果獲取的呢? 與Construction類相似,Method類中也提供了靜態(tài)方法getParamTypes,該方法返回描述參數(shù)類型的Class對象數(shù)組。此外,Method還提供了getReturnType方法,用于獲取返回類型的Class對象。

 

復(fù)制代碼

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

class Person {

   private String name = "蕭蕭弈寒";

   public String getName() {
       return name;
   }

   public void setName(String name) {
       this.name = name;
   }

   public static void speak() {
       // ...
   }

   public final void eat() {
       // ...
   }
}


public class ReflectionDemo1 {
   public static void main(String[] args) {

       Class cl = Person.class;

       Method[] methods = cl.getDeclaredMethods();
       for (Method m : methods) {
           // 返回類型的Class對象
           Class retType = m.getReturnType();
           //
           String retTypeName = retType.getName();

           // 獲取方法名
           String name = m.getName();

           String modifiers = Modifier.toString(m.getModifiers());
           if (modifiers.length() > 0) // 如果有修飾符
               System.out.print(modifiers + " ");

           // 返回值名
           System.out.print(retType.getName() + " ");

           System.out.print(name + "(");

           Class[] paramTypes = m.getParameterTypes();
           for (int i = 0; i if (i > 0) { // 如果不止一個(gè)參數(shù),用","分割
                   System.out.print(paramTypes[i].getName());
               }
           }
           System.out.println(");");
       }

   }
}

【運(yùn)行結(jié)果】: public java.lang.String getName(); public void setName(); public static void speak(); public final void eat();

解析域(Field)

Class類中的getDeclaredFields方法返回類中聲明的域數(shù)組,getFields方法返回類中的公有域、接口中的域所組成的Field對象數(shù)組。

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Field;
import java.util.Date;

class Person {
   private String name;
   protected int age;
   public Date birthday;
}

class Student extends Person implements Smoke{
   private float score;
}

interface Smoke {
   String brand = "大中華";
}

public class ReflectionDemo1 {
   public static void main(String[] args) {
       Class cl = Student.class;

       Field[] fields = cl.getFields();
       for (Field f : fields) {
           System.out.println(f);
       }
   }
}

【運(yùn)行結(jié)果】: public static final java.lang.String com.xiaoxiaoyihan.reflection.Smoke.brand public java.util.Date com.xiaoxiaoyihan.reflection.Person.birthday

結(jié)果顯示了字段由修飾符、類型**、*類名、字段名構(gòu)成。這里需要引入Field類中的*getType*方法,它返回*字段聲明類型的Class對象。下面同樣作出解析:

package com.xiaoxiaoyihan.reflection;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.Date;

class Person {
   private String name;
   protected int age;
   public Date birthday;
}

public class ReflectionDemo1 {
   public static void main(String[] args) {
       Class cl = Person.class;

       Field[] fields = cl.getDeclaredFields();
       for (Field f : fields) {
           // 屬性類型的Class對象
           Class type = f.getType();

           // 屬性類型名
           String name = type.getName();
           System.out.print(" ");

           // 修飾符
           String modifiers = Modifier.toString(f.getModifiers());

           if (modifiers.length() > 0) {   // 如果有修飾符
               System.out.print(modifiers + " ");
           }

           System.out.println(type.getName() + " " + name + ";");
       }
   }
}

【運(yùn)行結(jié)果】:

private java.lang.String java.lang.String; protected int int; public java.util.Date java.util.Date;


當(dāng)前名稱:JAVA的反射機(jī)制大總結(jié)
文章出自:http://m.5511xx.com/article/cddiosi.html