java-反射回顾笔记

Class和class

回顾java的数据类型,基本数据类型和引用数据类型,int,long,float,double,boolean,Object(?)
除了使用java定义的基本数据类型,自定义的类(或者接口)也是一种类型-- Class,每个类都有一个对应的Class实例

//如
Class class = new Class();
以String类为例,当JVM加载String类时,它首先读取String.class文件到内存,然后,为String类创建一个Class实例并关联起来:
Class cls = new Class(String);

而这个class实例是jvm在第一次加载某个类的时候自动创建的,注意我们用户并不能创建Class,代码层面解释的话就是Class类的构造方法是private类型的,这个Class实例保存了这个类的字段,方法,继承结构等等的信息,通过这个Class实例获取对应类(class)信息的方式,就叫反射

获取Class实例

//1.
Class c1= String.class;
//2.
String s = new String();
Class c2= s.getClass();
//3.
Class c3= Class.forName("java.lang.String");

获取字段信息

Field f1 = c2.getField("length");//根据字段名获取某个public的field(包括父类)(注意是public限制符)
Field f2 = c2.getDeclaredField("length");//根据字段名获取当前类的某个field(不包括父类)(没有限制符的限制)
Field[] f3 = c2.getFields();//同上
Field[] f4 = c2.getDeclaredFields();
//获取字段值
Object value = f.get(s);
System.out.println(value); 
//修改值
f.set(s,"sth");

获取成员方法信息

Method getMethod(name, Class...)//方法参数的Class实例,方法的意义同上
Method getDeclaredMethod(name, Class...)
Method[] getMethod()
Method[] getDeclaredMethod()

//public方法调用
invoke(Instance , Object...)//实例,方法入参
//静态方法调用
invoke(null, Object...)//静态方法与实例对象没有联系,所以传入的第一个参数永远为null(经过试验,调用静态方法第一个参数不影响调用)
//非公共方法调用同上公共方法,但是可能会调用失败,抛出IllegalAccessException
setAccessible(true);
//通过调用这个方法允许其调用,不过也可能会失败,jvm为了保护自己的核心类库会不允许

构造方法

有Class实例后可以使用Class实例创建新的实例对象0

String s= = String.class.newInstance();

这种创建方式的局限是只能调用该类的public无参构造方法,如果构造方法带有参数,或者不是public,就无法直接通过Class.newInstance()来调用
同样,java反射api也有构造方法的操作类,基本和Method一样,但是构造方法返回的结果就是一个实例,因为它是构造方法

Constructor cons = String.class.getConstructor(parameterTypes...);//无参可以传null

获取父类的Class

        Class n = s.getSuperclass();

获取实现的接口

	Class[] is = s.getInterfaces();

JDK动态代理

学习spring的过程中了解到的一个用法,我认为jdk的动态代理有一个最大的局限就是只能代理接口
先定义了接口Hello,但是并不去编写实现类,而是直接通过JDK提供的一个 Proxy.newProxyInstance() 创建了一个Hello接口对象。这种没有实现类但是在运行期动态创建了一个接口对象的方式,称为动态代码。JDK提供的动态创建接口对象的方式,就叫动态代理。

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Main {
    public static void main(String[] args) {
        InvocationHandler handler = new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                System.out.println(method);
                if (method.getName().equals("morning")) {
                    System.out.println("Good morning, " + args[0]);
                }
                return null;
            }
        };
        Hello hello = (Hello) Proxy.newProxyInstance(
            Hello.class.getClassLoader(), // 传入ClassLoader
            new Class[] { Hello.class }, // 传入要实现的接口
            handler); // 传入处理调用方法的InvocationHandler
        hello.morning("Bob");
    }
}

interface Hello {
    void morning(String name);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值