国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計(jì) > 正文

java反射機(jī)制

2019-11-14 15:30:30
字體:
供稿:網(wǎng)友

  java反射機(jī)制是在運(yùn)行狀態(tài)中,對于任意一個(gè)類,都能夠知道這個(gè)類的所有屬性和方法;對于任意一個(gè)對象,都能夠調(diào)用它的任意一個(gè)方法和屬性;這種動(dòng)態(tài)獲取的信息以及動(dòng)態(tài)調(diào)用對象的方法的功能稱為java語言的反射機(jī)制。

注意:反射是在運(yùn)行的時(shí)候進(jìn)行的,不是在編譯的時(shí)候運(yùn)行的。

反射的功能

Java反射機(jī)制主要提供了以下功能

  • 在運(yùn)行時(shí)判斷任意一個(gè)對象所屬的類;
  • 在運(yùn)行時(shí)構(gòu)造任意一個(gè)類的對象;
  • 在運(yùn)行時(shí)判斷任意一個(gè)類所具有的成員變量和方法;
  • 在運(yùn)行時(shí)調(diào)用任意一個(gè)對象的方法;生成動(dòng)態(tài)代理。

API簡介

在這里先看一下sun為我們提供了那些反射機(jī)制中的類:

  — java.lang.Class;        代表一個(gè)類

  — java.lang.reflect.Constructor; 代表類的構(gòu)造方法 

  — java.lang.reflect.Field;        代表類的成員變量(成員變量也稱為類的屬性)

  — java.lang.reflect.Method;  代表類的方法

  — java.lang.reflect.Array;  提供了動(dòng)態(tài)創(chuàng)建數(shù)組,以及訪問數(shù)組的元素的靜態(tài)方法

注意:java中無論生成某個(gè)類的多少對象, 這些對象都會(huì)對應(yīng)于同一個(gè)Class對象。

 

方法介紹

方法關(guān)鍵字

含義

getDeclaredMethods()

獲取所有的方法

getReturnType()

獲得方法的放回類型

getParameterTypes()

獲得方法的傳入?yún)?shù)類型

getDeclaredMethod("方法名",參數(shù)類型.class,……)

獲得特定的方法

 

 

構(gòu)造方法關(guān)鍵字

含義

getDeclaredConstructors()

獲取所有的構(gòu)造方法

getDeclaredConstructor(參數(shù)類型.class,……)

獲取特定的構(gòu)造方法

 

 

父類和父接口

含義

getSuperclass()

獲取某類的父類

getInterfaces()

獲取某類實(shí)現(xiàn)的接口

獲取Class的三種方式

1)、使用Class類的forName(String className)靜態(tài)方法。改方法需要傳入字符串參數(shù),改字符串參數(shù)的值是某個(gè)類的全限定類名(必須添加完整的包名)。

Class.forName("java.lang.String");

 

2)、調(diào)用某個(gè)的class屬性來獲取該類對應(yīng)的class對象,如

String.class

 

3)、調(diào)用某個(gè)對象的getClass方法。

String s = "aa";Class<?> clazz = s.getClass();

生成對象

1)、通過不帶參數(shù)的構(gòu)造方法生成對象有兩種方法

  a)、先獲得Class對象,然后通過該Class對象的newInstance()方法直接生成即可:

  newInstance()方法可以返回一個(gè)實(shí)例,但是構(gòu)造方法要是沒有參數(shù)列表的,它相當(dāng)于調(diào)用某個(gè)類的不帶參數(shù)的構(gòu)造方法,但是如果在初始化對象的時(shí)候要傳參數(shù),就要使用Constructor

Class<?> classType = String.class;
Object obj = classType.newInstance();

  b)、先獲得Class對象,然后通過該對象獲得相應(yīng)的Constructor對象,再通過該Constructor對象的newInstance()方法生成:

Class<?> classType = object.getClass();Constructor cons = classType.getConstructor(new Class[]{});Object obj = cons.newInstance(new Object[]{});

 

2)、若想通過類的帶參數(shù)的構(gòu)造方法生成對象,只能使用下面一種方式:

   Class<?> classType = object.getClass();   Constructor cons = classType.getConstructor(new Class[]{String.class,int.class});   Object obj = cons.newInstance(new Object[]{"hello",3});

 

  例子

public class ReflectTester{  //方法實(shí)現(xiàn)對Customer對象的拷貝操作 public Object copy(Object object) throws Exception {  Class<?> classType = object.getClass();  /*Constructor cons = classType.getConstructor(new Class[]{});   Object obj = cons.newInstance(new Object[]{});  System.out.PRintln(obj);  System.out.println("-----------");*/   //以上的兩行代碼等價(jià)于下面一行  //Object obj2 = classType.newInstance();  Constructor cons2 = classType.getConstructor(new Class[]{String.class, int.class});  Object obj2 = cons2.newInstance(new Object[]{"hello",3});  System.out.println(obj2);   return null; }  public static void main(String[] args) throws Exception {  ReflectTester test = new ReflectTester();  test.copy(new Customer()); } }class Customer{ private Long id;  private int age;  private String name;  public Customer() {  }  public Customer(String name,int age) {  this.name = name;  this.age= age; } public Long getId() {  return id; } public void setId(Long id) {  this.id = id; } public int getAge() {  return age; } public void setAge(int age) {  this.age = age; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } }

 

  相對復(fù)雜的例子

import java.lang.reflect.Constructor;import java.lang.reflect.Field;import java.lang.reflect.Method;public class ReflectTester{  //方法實(shí)現(xiàn)對Customer對象的拷貝操作 public Object copy(Object object) throws Exception {  Class<?> classType = object.getClass();  Object ObjectCopy = classType.getConstructor(new Class[]{}).newInstance(new Object[]{});   //獲得成員變量   Field[] fields = classType.getDeclaredFields();  for(Field field : fields)  {   String name = field.getName();      String firstLetter = name.substring(0,1).toUpperCase(); //將屬性的首字母轉(zhuǎn)換為大寫      String getMethodName = "get" + firstLetter + name.substring(1);      String setMethodName = "set" + firstLetter + name.substring(1);      Method getMethod = classType.getMethod(getMethodName, new Class[]{});      Method setMethod = classType.getMethod(setMethodName, new Class[]{field.getType()});      Object value = getMethod.invoke(object, new Object[]{});      setMethod.invoke(ObjectCopy, new Object[]{value});     }    return ObjectCopy; }  public static void main(String[] args) throws Exception {  Customer customer = new Customer("tom",20);   customer.setId(1L);   ReflectTester test = new ReflectTester();   Customer cus = (Customer)test.copy(customer);   System.out.println(cus.getAge()+","+cus.getName()+","+cus.getId()); } }class Customer{ private Long id;  private int age;  private String name;  public Customer() {  }  public Customer(String name,int age) {  this.name = name;  this.age= age; } public Long getId() {  return id; } public void setId(Long id) {  this.id = id; } public int getAge() {  return age; } public void setAge(int age) {  this.age = age; } public String getName() {  return name; } public void setName(String name) {  this.name = name; } }

  注意:Integer.TYPE返回的是int,而Integer.class返回的是Integer類所對應(yīng)的Class對象。

反射生成多維數(shù)組

import java.lang.reflect.Array;/** * * 用反射構(gòu)造一個(gè)多維數(shù)組 * */public class ArrayTester2 { public static void main(String[] args) {  int[] dims = new int[]{5,10,15};   //newInstance()方法的第二個(gè)參數(shù)是代表生成數(shù)組的維度,所以生成的數(shù)組維度為5,10,15,長寬高  Object array = Array.newInstance(Integer.TYPE,dims);   //arrayObj是一個(gè)二維的數(shù)組  Object arrayObj = Array.get(array,3);   Class<?> classType = arrayObj.getClass().getComponentType();   //arrayObj是一個(gè)一維的數(shù)組  arrayObj = Array.get(arrayObj, 5);   Array.setInt(arrayObj, 10, 37);   int[][][] arrayCast = (int[][][])array;   System.out.println(arrayCast[3][5][10]); }}

 

反射訪問私有(private)的方法

  private 限制的方法沒有辦法在另外的類中使用,但可以使用反射進(jìn)行使用。而getMethod()方法只能獲取public的方法。如果要使用private的方法就要使用 getDeclaredMethod()方法。

例子1、獲取privete方法、

public class PrivateTest { private String sayHello(String name) {    return "hello" + name; }}
import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class TestPrivate { public static void main(String[] args) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalaccessException, InvocationTargetException {  PrivateTest p = new PrivateTest();   Class<?> classType = p.getClass();   Method method = classType.getDeclaredMethod("sayHello", new Class[]{String.class});   method.setAccessible(true); //壓制java的訪問控制檢查   String str = (String)method.invoke(p, new Object[]{"aaa"});   System.out.println(str);  } }

 

例子2、改變private的屬性

public class Private2 { private String name = "zhangsan";  public String getName() {  return name; }}
/** * * 將Private2中的private屬性name的值變?yōu)槔钏?* */public class TestPrivate2{  public static void main(String[] args) throws Exception {  Private2 p = new Private2();   Class<?> classType = p.getClass();   Field field = classType.getDeclaredField("name");   field.setAccessible(true);   field.set(p, "lisi");   System.out.println(p.getName()); } }

 

  致謝:感謝您的閱讀!


發(fā)表評論 共有條評論
用戶名: 密碼:
驗(yàn)證碼: 匿名發(fā)表
主站蜘蛛池模板: 绥棱县| 伊宁市| 九龙坡区| 克拉玛依市| 全椒县| 彭泽县| 梁山县| 九江县| 海宁市| 平远县| 淳化县| 驻马店市| 余江县| 绍兴县| 鹤岗市| 巍山| 常熟市| 五指山市| 扬中市| 通化市| 敦煌市| 共和县| 白银市| 邯郸县| 张家口市| 长葛市| 英德市| 鄢陵县| 大石桥市| 宜阳县| 庆元县| 黑龙江省| 余干县| 建瓯市| 龙川县| 鲜城| 青岛市| 荥阳市| 涟源市| 天峻县| 资中县|