码迷,mamicode.com
首页 > 编程语言 > 详细

Java 基础 - 反射

时间:2016-07-13 16:52:34      阅读:256      评论:0      收藏:0      [点我收藏+]

标签:

基本概念

  • Java 反射机制可以让我们在编译期(Compile Time)之外的运行期(Runtime)检查类,接口,变量以及方法的信息。

  • 利用反射,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性。


Class

  • 想要获取一个类的信息,首先需要获取类的Class对象。

  • Java中的所有类型包括基本类型(int, long, float等等),即使是数组都有与之关联的Class类的对象。


获取类的对象

//在编译期知道一个类的名字
Class cls = Demo.class 

//在程序运行的时候获取类名(需要包括完整的包名)   
Cllss clas = Class.forName("com.test.Demo")

取得类名

Class cls = Demo.class 

//获取简单类名
String className = cls.getName();

//获取完整类型(包括包名)
String simpleClassName =cls.getSimpleName();

取得修饰符

Class cls =Demo.class;

// 修饰符都被包装成一个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 =Demo.class;
Package p = cls.getPackage();

取得继承的父类

Class cls =Demo.class;

//superclass 对象其实就是一个Class类的实例,可以继续在这个对象上进行反射操作
Class superClass  = cls.getSuperclass();

取得实现的接口

Class cls = Demo.class;

//由于一个类可以实现多个接口,所有返回的是接口数组,同样的接口中也有 Class 对象
Class [ ] interfaces = cls.getInterfaces();

Constructor

1.获取构造方法

获取所有的公共构造方法

class Demo {
    Demo() {}
    public Demo(String str) {}
    public Demo(String str, int num) {}
}

public class Test {
    public static void main(String[] args) {
        Class cls = Demo.class;

        Constructor[] constructors = cls.getConstructors(); 

        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
    }
}

// 输出结果:
// public Demo(java.lang.String)
// public Demo(java.lang.String,int)

获取指定的公共构造方法

//...省略 Demo 类

Class cls = Demo.class

// 若不存在匹配的公共构造函数,抛出 java.lang.NoSuchMethodException 异常
Constructor constructor = cls.getConstructor(new Class[]{String.class,int.class});  

2.获取构造方法参数

Constructor constructor = ...

//只提供获取所有构造参数的方法,没有获取指定参数的方法
Class [] paramterTypes = constructor.getParameterTypes();

3.利用构造函数实例化类

Class cls = ...
Constructor constructor = cls.getConstructor(new Class[]{String.class});

// newInstance 里面的参数,需要与构造函数的参数精确匹配才能生效
// 例如下面的例子中构造函数参数是 String,则在实例化类就必须提供一个 String 的对象(即 "demo")
Demo demo = (Demo) constructor.newInstance(new Object[]{"demo"});

Field

1.获取变量

获取所有变量(公共,非公共)

class Demo {
    boolean isTrue;
    private String str;
    public  int num;    
}   

public class Test {
    public static void main(String[] args) throws Exception {
        Class cls = Demo.class;
        Field[] fields = cls.getFields();
        Field [] privateFields =cls.getDeclaredFields();

        for(Field field : fields){
            System.out.println("公共参数:"+field);
        }

        for(Field privateField : privateFields){
            System.out.println("非公共参数:"+privateField);
        }
    }
}

// 输出结果:
// 公共参数:public int Demo.num
// 非公共参数:boolean Demo.isTrue
// 非公共参数:private java.lang.String Demo.str
// 非公共参数:public int Demo.num

获取指定变量(公共,非公共)

//...省略相同代码

Class cls = Demo.class;

//名称不匹配,抛出 java.lang.NoSuchFieldException 异常
Field field = cls.getField("num");
Field privateField = cls.getDeclaredField("str");

2.获取/设置变量值

Class<?> cls = Demo.class;
Demo demo = (Demo) cls.newInstance();

// setter
Field field = cls.getField("num");
field.set(demo, 1000);

//getter
int filedValue  = (Integer) field.get(demo);

// setter
Field privateField = cls.getDeclaredField("str");
// 关键 --> 设置访问权限
privateField.setAccessible(true);
privateField.set(demo, "hello");

//getter
String privateFieldValue = (String) privateField.get(demo);

// 输出结果
System.out.println(filedValue);
System.out.println(privateFieldValue);

Method

1.获取方法对象

获取所有方法

class Demo {
    public String  print(String str) {
        return str;
    }

    private void say(){
    }
}

public class Test {

    public static void main(String[] args) throws Exception {
        Class cls = Demo.class;

        // 包括从父类继承而来的
        Method[] methods = cls.getMethods();
        Method [] privateMethods = cls.getDeclaredMethods();
    }
}

获取指定方法

//...省略相同方法

Class cls = Demo.class;

//getMethod(方法名,方法参数类型)
Method method = cls.getMethod("print", new Class[]{String.class});
Method privateMethod = cls.getMethod("say", null);

2.获取方法参数类型

Method method = ...

//获取所有的参数类型
Class [] paramterTypes = method.getParameterTypes();

//获取返回类型
Class reeturnType = method.getReturnType();

3.调用方法

Class cls = Demo.class;
Demo demo = (Demo) cls.newInstance();
Method method = cls.getMethod("print", new Class[]{String.class});

//调用公用方法(类实例,方法的参数的具体值)
method.invoke(demo, "hello");

//调用私有方法
Method privateMethod = cls.getDeclaredMethod("print", new Class[]{String.class});
// 关键-->获得访问权限
privateMethod.setAccessible(true);
privateMethod.invoke(demo, "hello");

4.判断 getter/setter 方法

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;
}

Array

package com.controller;

import java.lang.reflect.Array;

public class Test{
    public static void main(String[] args) throws ClassNotFoundException {

        //创建一个数据
        int [ ] intArray = (int[]) Array.newInstance(int.class, 3);

        //访问一个数组
        Array.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));

        //获得数组的 Class 对象
        Class stringArrayClass = String[].class;

        //在JVM中字母I代表int类型,左边的‘[’代表我想要的是一个int类型的数组
        Class intArrayClass = Class.forName("[I");  

        //注意‘[L’的右边是类名,类名的右边是一个‘;’符号。这个的含义是一个指定类型的数组。
         stringArrayClass = Class.forName("[Ljava.lang.String;");   

        //获取数组的成员类型
        String [ ] strings = new String[3];
        Class stringsArrayClass = strings.getClass();
        Class stringsArrayComponentType =stringsArrayClass.getComponentType();
        System.out.println(stringsArrayClass);

    }
}

Java 基础 - 反射

标签:

原文地址:http://blog.csdn.net/u012420654/article/details/51892526

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!