首頁  >  文章  >  Java  >  08.Java 基礎 - 反射

08.Java 基礎 - 反射

黄舟
黄舟原創
2017-02-27 10:35:231063瀏覽


基本概念


Java 反射機制可以讓我們在編譯期(Compile Time )以外的運行期(Runtime)檢查類,接口,變數以及方法的資訊。

反射的作用如下:

  • 對於任意一個類,都能夠知道這個類別的所有屬性和方法;

  • 對於任意一個對象,都能夠呼叫它的任意一個方法和屬性。


Class

想要取得一個類別的信息,首先需要取得類別的 Class 物件。

Java中的所有型別包括基本型別(int、long、float 等),即使是陣列都有與之關聯的 Class 物件。

  • 取得類別的物件

#
//1.在编译期获取类对象Class cls = Demo.class 

//2.在运行期获取类对象(注意:需要包括完整的包名) Cllss clas = Class.forName("com.test.Demo")
  • 取得類別的名稱

Class cls = ...// 1.获取完整类型(包括包名)String className = cls.getName();
// 2.获取简单类名 String simpleClassName =cls.getSimpleName();
  • 取得類別的修飾符

Class cls = ...// 修饰符都被包装成一个 int 类型的数字,这样每个修饰符都是一个位标识(flag bit)    
int modifiers  = cls.getModifiers();// 判断修饰符类型Modifier.isPublic( modifiers);
Modifier.isProtected( modifiers);
Modifier.isPrivate( modifiers);
Modifier.isAbstract( modifiers);
Modifier.isInterface( modifiers);
Modifier.isFinal( modifiers);
Modifier.isStatic( modifiers);
Modifier.isNative( modifiers);
Modifier.isStrict( modifiers);
Modifier.isSynchronized( modifiers);
Modifier.isTransient( modifiers);
Modifier.isVolatile( modifiers);
  • 取得類別所在的套件資訊

Class cls =...
Package p = cls.getPackage();
  • #取得類別繼承的父類別

Class cls = ...
Class superClass  = cls.getSuperclass();
  • 取得類別實作的介面類型

#
Class cls = ...// 类可以实现多个接口,因此返回的是接口数组Class [ ] interfaces = cls.getInterfaces();

Constructor

#在Java 中,Constructor 類別用表示一個建構器物件。

  • 取得公用建構方法

#
Class cls = ...// 1.获取所有构造函数Constructor[] constructors = cls.getConstructors(); 

// 2.获取指定构造函数,不存在匹配则抛出异常。
// 对应的构造函数入参类为 Person(String str, int i)Constructor constructor = 
    cls.getConstructor(new Class[]{String.class,int.class});
  • 取得建構子的入參型別

Constructor constructor = ...
// 因为构造函数的入参有多个,因此返回的数组Class [] paramterTypes = constructor.getParameterTypes();
for(Class paramterType: paramterTypes ){    
// do something...}
  • 建構子實例化類別

Class cls = ...
Constructor constructor = cls.getConstructor(new Class[]{String.class});
// Object[] 数组表示入参的具体值,需要与 Class[] 的入参类型完全匹配Demo demo = (Demo) constructor.newInstance(new Object[]{"hello"});

Field

在Java 中,Field類別用表示一個變數物件。

  • 取得所有變數(公共,非公共)

#
Class cls = ...// 1.获取所有公共变量Field[] fields = cls.getFields();
// 2.获取所有非公共变量Field [] privateFields =cls.getDeclaredFields();
  • ##取得指定變數(公共,非公共)

  • Class cls = ...//入参为变量名称,名称不匹配则抛出异常// 获取指定公共变量Field field = cls.getField("num");
    // 获取指定非公共变量Field privateField = cls.getDeclaredField("str");
  • #操作變數

    ##
    Class<?> cls = Demo.class;
    Demo demo = (Demo) cls.newInstance();// 1.1.公共方法的 setter、getterField field = cls.getField("num");
    field.set(demo, 1000);int filedValue  = (Integer) field.get(demo);// 2.1 非公共方法的 setter、getterField privateField = cls.getDeclaredField("str");
    privateField.setAccessible(true); // 关键 -> 操作之前,需要设置访问权限privateField.set(demo, "hello");
    String privateFieldValue = (String) privateField.get(demo);

Method

1.取得方法物件

  • #取得所有方法

    Class cls = ...// 1.获取所有公共方法(包括从父类继承而来的)Method[] methods = cls.getMethods();
    // 2.获取所有非公共方法(包括从父类继承而来的)Method [] privateMethods = cls.getDeclaredMethods();
  • 取得指定方法

    #
    Class cls = ...// 1.获取指定公共方法,入参为:方法名、方法入参Method method = cls.getMethod("print", new Class[]{String.class});
    // 2.获取指定非公共方法,入参为:方法名、方法入参Method privateMethod = cls.getDeclaredMethod("say", new Class[]{int.class});
  • 取得方法的參數類型

    Method method = ...// 1.获取方法的所有入参类型Class [] paramterTypes = method.getParameterTypes();
    // 2.获取方法的返回值类型Class reeturnType = method.getReturnType();
  • #執行方法

    Class cls = Demo.class;
    Demo demo = (Demo) cls.newInstance();
    Method method = cls.getMethod("print", new Class[]{String.class});//1.执行公用方法,入参为:类实例,方法入参的具体值method.invoke(demo, "hello");
    //2.执行非公共方法Method privateMethod = 
        cls.getDeclaredMethod("print", new Class[]{String.class});
    privateMethod.setAccessible(true); // 关键 -> 操作之前,需要获得访问权限privateMethod.invoke(demo, "hello");

public static boolean isGetter(Method method){    
if(!method.getName().startsWith("get")){        
return false;
    }    
    if(method.getParameterTypes().length !=0){        
    return false;
    }    
    if(void.class.equals(method.getReturnType())){        
    return false;
    }    
    return true;
}
public static boolean isSetter(Method method){    
if(!method.getName().startsWith("set")){        
return false;
    }    
    if(method.getParameterTypes().length !=1){        
    return false;
    }    
    return true;
}

  • 判斷getter/setter 方法

    int [ ] intArray = ... 
    Class arrayCls = intArray.class;
    Array
  • 在Java 中,用Array 類表示數組物件。

    取得陣列物件
  • #

    Class arrayCls = ...
    Class arrayComponentType =arrayCls .getComponentType();

    取得陣列成員類型
  • // 创建一个数组,类型为 int ,容量为 3int [ ] intArray = (int[]) Array.newInstance(int.class, 3);
    //在 JVM 中字母I代表int类型,左边的‘[’代表我想要的是一个int类型的数组Class intArrayClass = Class.forName("[I");  
    
    //注意‘[L’的右边是类名,类名的右边是一个‘;’符号。这个的含义是一个指定类型的数组。
     stringArrayClass = Class.forName("[Ljava.lang.String;");

#建立陣列


#

int [ ] intArray = ...// 添加元素,数组为 intArray,位置为 0 ,值为 100Array.set(intArray, 0, 100);
Array.set(intArray, 1, 200);
System.out.println("intArray[0] = " + Array.get(intArray, 0));
System.out.println("intArray[1] = " + Array.get(intArray, 1));

#########新增陣列元素############rrreee### 以上就是08.Java 基礎- 反射的內容,更多相關內容請關注PHP中文網(www.php.cn)! ################
陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn