深入剖析Java的反射机制

一、反射机制的具体概念表述:

关于反射:在计算机领域,反射指的是一种能够自我描述以及自我控制的应用。
引用维基百科的解释:

在计算机学中,反射(英语:reflection)是指计算机程序在运行时(runtime)可以访问、检测和修改它本身状态或行为的一种能力。用比喻来说,反射就是程序在运行的时候能够“观察”并且修改自己的行为。

要注意术语“反射”和“内省”(type introspection)的关系。内省(或称“自省”)机制仅指程序在运行时对自身信息(称为元数据)的检测;反射机制不仅包括要能在运行时对程序自身信息进行检测,还要求程序能进一步根据这些信息改变程序状态或结构。

反射机制简介:主要是指,程序可以访问、检测和修改它本身状态活性位的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

二、Java反射机制的用途:

1,反编译:.class–>.java

2,通过反射机制访问java对象的属性,方法,构造方法等;

	1).判断任意一个对象所属的类;
	2).构造任意一个类的对象;
	3).判断任意一个类所具有的成员变量和方法;
	4).调用任意一个对象的方法;
	5).生成动态代理。

3, 基本运用:

	3.1 获取Class对象:
	1)使用Class类的forName静态方法;

在这里插入图片描述

	2)直接获取一个对象的class;

在这里插入图片描述

	3)调用某个对象的getClass()方法。

在这里插入图片描述

   	3.2 判断是否为某个类的实例:
	——关键字instanceof
	——方法isInstance():是一个native方法(一个java调用非java代码的接口)
private native boolean isInstance(Object obj);
	3.3 创建实例:
	1)使用Class对象的newInstance()方法进行创建:
Class<?> c = String.class;
Object str = c.newInstance();
Class c3 = user.getClass();
Object obj = c3.newInstance();
2) 通过Class对象获取指定的Constructor对象,再调用Constructor对象的newInstance()方法来创建实例。这种方法可以用指定的构造器构造类的实例。
//获取String所对应的Class对象
Class<?> c = String.class;
//获取String类带一个String参数的构造器
Constructor constructor = c.getConstructor(String.class);
//根据构造器创建实例
Object obj = constructor.newInstance("23333");
System.out.println(obj);
3.4获取方法:
	1)getDeclaredMethods() 方法返回类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法。返回的是一个Method类型的数组。

方法声明:

	
public Method[] getDeclaredMethods() throws SecurityException

使用案例:

Class c1 = Class.forName("com.jyk.Entity.User");
Method[] methods = c1.getDeclaredMethods();
for (Method m: methods
                 ) {
                System.out.println(m);
            }
	2)getMethods方法返回某个类的所有公用方法(public),包括其继承类的公用方法。(可以获取到父类的方法)

方法声明:

public Method[] getMethods() throws SecurityException

使用案例:

      Method[] methods1 = c1.getDeclaredMethods();
            for (Method m:methods1
                 ) {
                System.out.println(m);
            }
	3)getMethod()方法返回一个特定的方法,其中第一个参数为方法名称,后面的参数为方法的参数对应的Class对象。

方法声明:

public Method getMethod(String name, Class<?>... parameterTypes)

使用案例:

 Method method2 = c1.getMethod("setUserAge", String.class);
            System.out.println(method2);

	3.5 获取类的构造器信息getConstructor()——根据反射获得的类构造器信息创建实例newInstance():
Constructor[] methods2 = c1.getConstructors();
            for (Constructor c:methods2
                 ) {
                System.out.println(c);
            }

输出结果

public T newInstance(Object... initargs)
	3.6 获取类的成员变量(字段)信息:
	主要方法:
	getFiled():访问共有的成员变量
	getDeclaredFiled():所有已声明的成员变量,但不能得到其父类的成员变量。
 Field[] f = c.getDeclaredFields();
            StringBuffer s = new StringBuffer();
            s.append(Modifier.toString(c.getModifiers()) + " class " + c.getSimpleName() + "{\n");
            for (Field ff : f) {
                s.append("\t");
                s.append(Modifier.toString(ff.getModifiers()) + " ");
                s.append(ff.getType().getSimpleName() + " ");
                s.append(ff.getName() + ";\n");
            }
            s.append("\n}");
            System.out.println(s);
	3.7 调用方法:
	使用invoke()方法来调用从类中获得的方法:
	invoke()方法原型:
public Object invoke(Object obj, Object... args)
        throws IllegalAccessException, IllegalArgumentException,
           InvocationTargetException
	使用实例:
public class test1 {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
        Class<?> klass = methodClass.class;
        //创建methodClass的实例
        Object obj = klass.newInstance();
        //获取methodClass类的add方法
        Method method = klass.getMethod("add",int.class,int.class);
        //调用method对应的方法 => add(1,4)
        Object result = method.invoke(obj,1,4);
        System.out.println(result);
    }
}
class methodClass {
    public final int fuck = 3;
    public int add(int a,int b) {
        return a+b;
    }
    public int sub(int a,int b) {
        return a+b;
    }
}
3.8利用反射创建数组:
原理说明:以获取到的类为参数创建一个Array类对象,向该对象中添加新元素。
public static void testArray() throws ClassNotFoundException {
        Class<?> cls = Class.forName("java.lang.String");
        Object array = Array.newInstance(cls,25);
        //往数组里添加内容
        Array.set(array,0,"hello");
        Array.set(array,1,"Java");
        Array.set(array,2,"fuck");
        Array.set(array,3,"Scala");
        Array.set(array,4,"Clojure");
        //获取某一项的内容
        System.out.println(Array.get(array,3));
    }
	Array类原型:java.lang.reflect.Array类
public static Object newInstance(Class<?> componentType, int length)
        throws NegativeArraySizeException {
        return newArray(componentType, length);
    }

三、反射机制主要涉及的类和方法:


在这里插入图片描述

在这里插入图片描述

四、主要方法:

主要涉及的方法基本上已经在上文介绍过。

五、反射机制的优缺点:

优点:
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能

缺点:
(1)使用反射会额外消耗一定的系统资源,性能较低 ,如果不需要动态地创建对象,那么就不需要使用反射。
(2)使用反射会忽略权限检查,破坏了封装性,相对来说不安全

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值