Java的反射

java.lang.Class类

java.lang.Class主要提供了以下两个功能:

  1. 提供方法用于访问运行期间类的元数据;
  2. 提供方法用于检查和修改类的运行时行为;

java.lang.Class类常用方法

MethodDescription
1) public String getName()返回类名
2) public static Class forName(String className)throws ClassNotFoundException加载类并返回Class对象
3) public Object newInstance()throws InstantiationException,IllegalAccessException创建实例对象
4) public boolean isInterface()判断是否是接口
5) public boolean isArray()判断是否是数组
6) public boolean isPrimitive()判断是否是原始数据类型
7) public Class getSuperclass()返回父类Class引用
8) public Field[] getDeclaredFields()throws SecurityException返回类的成员属性字段数组
9) public Method[] getDeclaredMethods()throws SecurityException返回类的方法数组
10) public Constructor[] getDeclaredConstructors()throws SecurityException返回类的构造方法数组
11) public Method getDeclaredMethod(String name,Class[] parameterTypes)throws NoSuchMethodException,SecurityException
返回类中指定参数类型的方法

获取Class对象的三种方式

有三种方式,如下:

  1. Class类的forName()方法,动态加载,运行时,开始装入类, 并做类的静态初始化
  2. 对象的getClass()方法,静态加载(编译时已加载)
  3. .class语法, 静态加载(编译时已加载)

通过反射创建对象

有两种方式,如下:

  1. 通过Class对象的newInstance()方法创建,这种方式只能调用无参构造方法;
  2. 通过Constructor对象的newInstance()方法创建,这种方式适用于有参构造方法,并且还可以破坏单例模式,调用私有构造方法;

所以,通常来讲,第二种方式比第一种使用范围更广


Class对象调用newInstance()方法示例
package dai;
class TestDai{}public class Test{ public static void main(String args[]) { try { Class<?> c = Class.forName("dai.TestDai"); TestDai td = (TestDai) c.newInstance(); } catch (Exception e) { System.out.println(e); } }}

Constructor对象调用newInstance()方法示例

注意这里可以根据传入参数的类型来得到指定的构造方法,还可以改变构造方法的访问权限限制。

package dai;

import java.lang.reflect.Constructor;

class TestDai{
    private String msg;
    void message()
    {
        System.out.println("Hello" + msg);
    }
    private Simple(String msg){
        this.msg = msg;
    }
}

public class Test
{
    public static void main(String args[])
    {
        try
        {
            Class<?> c = Class.forName("dai.TestDai");
            Constructor<?> con = c.getDeclaredConstructor(String.class);
            con.setAccessible(true);  //设置可访问权限的限制
            TestDai  td = (TestDai) con.newInstance("Java");
            td.message();
        }
        catch (Exception e)
        {
            System.out.println(e);
        }

    }
}




通过反射调用私有方法

通过反射,我们可以调用其它类的私有方法,主要涉及java.lang.Class和java.lang.reflect.Method类;

其中主要是用到了Method类的setAccessible方法和invoke方法,前者修改访问权限,后者调用方法

通过调用有参私有方法示例:

package dai;

import java.lang.reflect.Method;

class A
{
    private void message(int n)
    {
        System.out.println(n);
    }
}

class Test
{
    public static void main(String args[]) throws Exception
    {
        Class<A> a = A.class;
        Object obj = a.newInstance();

        Method m = a.getDeclaredMethod("message", new Class[]{ int.class });
        m.setAccessible(true);
        m.invoke(obj, 8);
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值