Java Class反射

目录

一、Class

1.概念:

2.获取Class对象

3.创建运行时类的对象

二、获取运行时类的属性结构

三、获取运行时类的方法

四、获取运行时类的其他属性

五、获取指定运行时类的属性和方法

六、获取运行时类指定的构造器

七、动态代理模式

一、Class

1.概念:

Class的实例化对象就是一个运行时类。此外,实例还包括接口、基本数据类型、数组、枚举、注解、void ,加载到内存中的运行时类,会缓存一定的时间,在此时间内,我们可以通过不同的方式去获取该运行类。

2.获取Class对象

四种方式:代码如下

    @Test
    //Class实例化
    public void test() throws ClassNotFoundException {
        //方式一:调用运行时类的属性
        Class<Person> clazz1=Person.class;
        System.out.println(clazz1);
        //方式二:通过运行时类的对象,代用getClass()
        Person p1=new Person();
        Class clazz2= p1.getClass();
        System.out.println(clazz2);
        //方式三:调用Class的静态方法,forname(String classpath)
        Class clazz3=Class.forName("reflection.Person");
        System.out.println(clazz3);
        //方式四:使用类的加载器ClassLoader(了解即可)
        ClassLoader classloader=demo1.class.getClassLoader();
        Class clazz4= classloader.loadClass("reflection.Person");
        System.out.println(clazz4);

    }

3.创建运行时类的对象

    @Test
    public void test() throws InstantiationException, IllegalAccessException {
        Class<Person> clazz= Person.class;
        Person p1=clazz.newInstance();
        System.out.println(p1);


    }

二、获取运行时类的属性结构

package reflectionexample;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/*获取运行时类的属性结构*/
public class FieldTest {
    @Test
    public void test1(){
        Class clazz= Person.class;
        Field[]fields= clazz.getFields();//获取当前运行类及父类中声明为public的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println();
        Field[]fields1=clazz.getDeclaredFields();//获取当前类中声明的所有属性(不包含父类中声明的属性)
        for (Field field : fields1) {
            System.out.println(field);
        }

    }
    //权限修饰符 变量名 数据类型
    @Test
    public void test2(){
        Class clazz=Person.class;
        Field[]fields=clazz.getDeclaredFields();
        for (Field field : fields) {
            //权限修饰符
            int modifiers = field.getModifiers();
            System.out.print(Modifier.toString(modifiers)+"\t");
            //变量名
            String name=field.getName();
            System.out.print(name+"\t");
            //数据类型
            Class type = field.getType();
            System.out.println(type.getName()+"\t");

        }
    }
}

三、获取运行时类的方法

package reflectionexample;

import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;

public class methodTEst {
    //获取运行时类的方法
    @Test
    public void test1(){
        Class clazz=Person.class;
        Method []methods=clazz.getMethods();//获取当前运行时类和父类中声明的Public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        System.out.println("*****************************************************************");
        Method []methods2=clazz.getDeclaredMethods();//获取当前运行时类的所有方法,不包括父类中声明的方法
        for (Method method : methods2) {
            System.out.println(method);
        }
    }
    //获取运行时类的方法极其内部结构
    @Test
    public void test2(){
        Class clazz=Person.class;
        Method[]methods=clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method);
        //获取方法声明的注解
            Annotation[] annotations = method.getAnnotations();
            for (Annotation annotation : annotations) {
                System.out.println(annotation);
            }

        //权限修饰符
            System.out.print(Modifier.toString(method.getModifiers())+"\t");
        //返回值类型
            System.out.print(method.getReturnType().getName()+"\t");
        //方法名
            System.out.println(method.getName());
        //形参列表
            Class [] parameterTypes = method.getParameterTypes();
            if(!(parameterTypes.length==0&&parameterTypes==null))
            for (Class parameterType : parameterTypes) {
                System.out.print(parameterType.getName()+"\t");
            }
            //异常
            Class[] exceptionTypes = method.getExceptionTypes();
            if(exceptionTypes.length>0){
                for (Class exceptionType : exceptionTypes) {
                    System.out.println(exceptionType.getName());
                }
            }
        }

    }
}

四、获取运行时类的其他属性

package reflectionexample;

import com.sun.security.jgss.GSSUtil;
import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

public class OtherTest {
    //获取构造器
    @Test
    public void test(){
        Class clazz=Person.class;
        Constructor[] constructors = clazz.getConstructors();//获取当前运行时类中声明为public的构造器
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        System.out.println("****************************************************");
        Constructor[] declaredConstructors = clazz.getDeclaredConstructors();//获取当前运行时类中声明的所有的构造器
        for (Constructor de : declaredConstructors) {
            System.out.println(de);

        }
    }
    //获取运行时类的父类
    @Test
    public void test02(){
        Class clazz=Person.class;
        Class superclass = clazz.getSuperclass();
        System.out.println(superclass);
    }
    //获取运行时类带泛型的父类
    @Test
    public void test03(){
        Class clazz=Person.class;
        Type genericSuperclass = clazz.getGenericSuperclass();
        System.out.println(genericSuperclass);
    }
    //获取运行时类带泛型的父类的泛型
    @Test
    public void test04(){
        Class clazz=Person.class;
        Type genericSuperclass = clazz.getGenericSuperclass();
        ParameterizedType parameterizedType=(ParameterizedType)genericSuperclass;
        Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();
        System.out.println(actualTypeArguments[0].getTypeName());
    }
    //获取运行时类及父类的实现的接口
    @Test
    public void test05(){
        Class clazz=Person.class;
        Class[] interfaces = clazz.getInterfaces();
        for (Class anInterface : interfaces) {
            System.out.println(anInterface);
        }
        System.out.println("***********************");
        Class[] interfaces1 = clazz.getSuperclass().getInterfaces();
        for (Class aClass : interfaces1) {
            System.out.println(aClass);
        }
    }
    //获取运行时类所在的包
    @Test
    public void test06(){
        Class clazz=Person.class;
        Package aPackage = clazz.getPackage();
        System.out.println(aPackage);
    }
    //获取运行时类的注解
    @Test
    public void test07(){
        Class clazz=Person.class;
        Annotation[] annotations = clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
    }
}

五、获取指定运行时类的属性和方法

package reflectionexample;

import org.junit.Test;

import java.lang.reflect.Field;
import java.lang.reflect.Method;

//调用运行时类中指定的结构:属性 方法 构造器
public class UseMetodsTest {
    //获取指定的属性
    //方式1
    @Test
    public void test01() throws Exception {
         Class clazz=Person.class;
         Person p=(Person)clazz.newInstance();
        Field weight = clazz.getField("weight");//该方式只能获取权限为Public的属性
        weight.set(p,101);//需要先指定对象,然后再赋值
        Object o = weight.get(p);
        System.out.println((int)o);
    }
    //方式2
    @Test
    public void test02() throws Exception {
        Class <Person>clazz= Person.class;
        Person p=clazz.newInstance();
        Field name = clazz.getDeclaredField("name");//获取运行时类的指定变量名的属性
        name.setAccessible(true);//保证当前属性是可以访问的
        name.set(p,"ingram");
        Object o = name.get(p);
        System.out.println((String)o);
    }
    //操作运行时类的指定的方法
    @Test
    public void test03() throws Exception {
        Class<Person>clazz=Person.class;
        Person p=clazz.newInstance();
        Method show = clazz.getDeclaredMethod("show", String.class);//获取方法
        show.setAccessible(true);//保证当前方法是可以访问的
        Object nation=show.invoke(p,"China");//返回值是show方法的返回值
        System.out.println(nation);

        //访问静态方法
        Method out = clazz.getDeclaredMethod("miss");
        out.setAccessible(true);
        out.invoke(Person.class);


    }
}

六、获取运行时类指定的构造器

package reflectionexample;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

//获取运行时类的构造器
public class UseConstructorTest {
    @Test
    public void test() throws NoSuchMethodException, InvocationTargetException, InstantiationException, IllegalAccessException {
        Class clazz=Person.class;
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class,int.class);
        declaredConstructor.setAccessible(true);
        Person o = (Person) declaredConstructor.newInstance("蒲汶文", 21);
        System.out.println(o);
    }
}

七、动态代理模式

即不用重复写多个代理类来实现被代理类的方法,只需创建一个代理类来调用各个被代理类的方法即可。

package DynamicProxy;
//动态代理的举例

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

interface Human{
    String getbelief();
    void eat(String food);
}
//被代理类
class Superman implements Human{

    @Override
    public String getbelief() {
        return "I believe I can fly! ";
    }

    @Override
    public void eat(String food) {
        System.out.println("我喜欢吃"+food);

    }
}
class ProxyFactory{
    //此方法用于返回一个代理类对象
    public static Object getProxyInstance(Object obj){//obj是被代理类对象
        myInterface myInterface=new myInterface();
        myInterface.bind(obj);
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),myInterface);
    }
}
class myInterface implements InvocationHandler{
    private Object obj;
    public void bind(Object obj){
        this.obj=obj;
    }
    //当我们通过代理类对象调用方法a时,就会自动调用如下方法:invoke()
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //method即为代理类对象调用的方法,此方法也就作为了被代理对象要调用的方法
        Object invoke = method.invoke(obj, args);
        return invoke;
    }
}
public class Proxytest{
    public static void main(String[] args) {
        Superman superman=new Superman();
        Human proxyInstance =(Human) ProxyFactory.getProxyInstance(superman);
        String res= proxyInstance.getbelief();
        System.out.println(res);
        proxyInstance.eat("鸡公煲");
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值