JavaSE-反射

package com.btp.t4.Reflection;

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

import org.junit.Test;

public class TestRefletion {
    //没有反射的情况下
    @Test
    public void test1(){
        Person p=new Person("btp",24);
        p.show();
        p.display("China");
        
    }
    //有反射的情况下,可以通过反射创建一个类的对象,并调用其中的结构
    @Test
    public void test2() throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException{
        Class clazz=Person.class;
        //1.创建clazz对应的类运行时类Person类的对象
        Person p=(Person)clazz.newInstance();
        System.out.println(p);
        //2.通过反射调用运行时类的指定的属性
        //2.1 public属性
        Field f1=clazz.getField("name");
        f1.set(p, "btp");
        System.out.println(p);
        //2.2 private属性
        Field f2=clazz.getDeclaredField("age");
        f2.setAccessible(true);
        f2.set(p, 24);
        System.out.println(p);
        //3.通过反射调用运行时类的指定方法
        Method m1=clazz.getMethod("show");
        m1.invoke(p);
        Method m2=clazz.getMethod("display", String.class);
        m2.invoke(p, "China");
    }
    
    /*
     * java.lang.Class:是反射的源头
     * 我们创建了一个类,通过编译(javac.exe),生成对应的.class文件。之后我们使用java.exe加载(JVM的加载器)
     * 此.class文件。此.class文件加载到内存以后,就是一个运行时类,存放在缓存区。那么这个运行时类的本身就是
     * 一个Class的实例。//Class c1=String.class;...
     * 1.每一个运行时类只加载一次(加载以后存放在缓存中)
     * 2.有了Class的实例以后,我们才可以进行以下的操作:
     *           ①创建对应的运行时类的对象
     *           ②获取对应的运行时类的完整结构(属性,方法,构造器,内部类,父类,所在的包,异常,注释...)
     *           ③调用对应的运行时类的指定的结构(属性,方法,构造器)
     *           ④反射的应用:动态代理
     */
    @Test
    public void test3(){
        Person p=new Person();
        Class clazz=p.getClass();//通过运行时类的对象,调用其getClass(),返回其运行时类
        System.out.println(clazz);
    }
    
    //如何获取Class的实例(3种)
    @Test
    public void test4() throws ClassNotFoundException{
        //1.调用运行时类本身的.class属性
        Class class1=Person.class;
        System.out.println(class1.getName());
        Class class2=String.class;
        System.out.println(class2);
        //2.通过运行时类的对象获取
        Person p=new Person();
        Class class3=p.getClass();
        System.out.println(class3.getName());
        //3.通过Class的静态方法获取
        String Classname="com.btp.t4.Reflection.Person";//类所在的完整路径
        Class class4=Class.forName(Classname);
        System.out.println(class4.getName());
        //4.(了解)通过类的加载器
        ClassLoader classloader=this.getClass().getClassLoader();//先创建一个类加载器的对象
        Class class5=classloader.loadClass(Classname);//通过类加载器的对象的loadClass()方法返回一个Class的实例
        System.out.println(class5.getName());
    }
}
class Person{
    public String name;
    private int age;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public Person() {
        super();
        // TODO 自动生成的构造函数存根
    }
    public Person(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    public void show(){
        System.out.println("我是一个人!");
    }
    public void display(String nation){
        System.out.println("我的国籍是:"+nation);
    }
    
}
TestRefletion
package com.btp.t4.Reflection;

import java.io.Serializable;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;

import org.junit.Test;

public class TestConstructor {
    @Test
    public void test1() throws InstantiationException, IllegalAccessException{
        Class class1=PersonP.class;
        //创建相应的类的对象,使用newInstance(),实际上就是调用了运行时类的空参的构造器
        Object obj=class1.newInstance();//1.要求对应的运行时类要有空参构造器 2.构造器要有足够访问权限
        PersonP p=(PersonP)obj;
        System.out.println(p);    
    }
    
    //获取对应的运行时类的属性
    @Test
    public void test2(){
        Class clazz=PersonP.class;
        Field[] fields=clazz.getFields();//只能获取到运行时类及其父类中声明为public的属性
        for(Field f:fields){
            System.out.println(f);
        }
        System.out.println();
        fields=clazz.getDeclaredFields();//获取运行时类本身所有的属性
        for(Field f:fields){
            System.out.println(f);
        }
    }
    
    //获取属性的各个部分的内容
    @Test
    public void test3(){
        Class clazz=PersonP.class;
        Field[] fields=clazz.getDeclaredFields();//获取运行时类本身所有的属性
        for(Field f:fields){
            //1.获取每个属性的权限修饰符
            String s=Modifier.toString(f.getModifiers());
            System.out.println(s);
            //2.获取每个属性的变量类型
            Class t=f.getType();
            System.out.println(t.getName());
            //3.获取属性名
            System.out.println(f.getName());
            
            System.out.println();
        }
    }
    
    //获取运行时类的方法
    @Test
    public void test4(){
        Class clazz=PersonP.class;
        //getMethods()获取运行时类及其父类中声明为public的方法
        Method[]m=clazz.getMethods();
        for(Method m1:m){
            System.out.println(m1);
        }
        System.out.println();
        //getDeclaredMethods():获取运行时类本身声明的所有方法
        m=clazz.getDeclaredMethods();
        for(Method m1:m){
            System.out.println(m1);
        }
    }
    
    //注解  权限修饰符  返回值类型  方法名  形参列表  异常
        @Test
        public void test5(){
            Class clazz=PersonP.class;
            int i=1;
            Method[]m=clazz.getDeclaredMethods();
            for(Method m1:m){
                //1.注解
                
                Annotation[]ann=m1.getAnnotations();
                System.out.println("方法"+i+"的注解:");
                for(Annotation a:ann){
                    System.out.println(a);
                }
                
                
                //2.权限修饰符
                String s=Modifier.toString(m1.getModifiers());
                System.out.println("方法"+i+"的权限修饰符:");
                System.out.println(s);
                //3.返回值类型
                Class rt=m1.getReturnType();
                System.out.println("方法"+i+"的返回值类型:");
                System.out.println(rt.getName());
                //4.方法名
                System.out.println("方法"+i+"名:");
                System.out.println(m1.getName());
                //5.形参列表
                Class[] cl=m1.getParameterTypes();
                System.out.println("方法"+i+"的形参列表:");
                for(Class l:cl){
                    System.out.println(l.getName());
                }
                //6.异常
                Class[] cl1=m1.getExceptionTypes();
                System.out.println("方法"+i+"的异常:");
                for(Class l:cl1){
                    System.out.println(l.getName());
                }
                i++;
            }
        }
        
        @Test
        public void test6(){
            Class clazz=PersonP.class;
            Constructor[] cons=clazz.getDeclaredConstructors();
            for(Constructor c:cons){
                System.out.println(c);
            }
        }
        
        @Test
        public void testOthers(){
            //1.获取运行时类的父类
            Class clazz=PersonP.class;
            Class sc=clazz.getSuperclass();
            System.out.println(sc);
            //2.获取带泛型的父类
            Type type1=clazz.getGenericSuperclass();
            System.out.println(type1);
            //3.获取父类的泛型
            ParameterizedType param=(ParameterizedType)type1;
            Type[] ars=param.getActualTypeArguments();
            System.out.println(((Class)(ars[0])).getName());
            //4.获取实现的接口
            Class[] interfaces=clazz.getInterfaces();
            for(Class c:interfaces){
                System.out.println(c);
            }
            //5.获取所在的包
            Package pack=clazz.getPackage();
            System.out.println(pack);
            //6.获取注解
            Annotation[] anns=clazz.getAnnotations();
            for(Annotation a:anns){
                System.out.println(a);
            }
        }
        
        //※通过反射调用运行时类的指定的属性
        @Test
        public void testGetFiled() throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException{
            Class clazz=PersonP.class;
            //1.获取指定的属性
            Field name=clazz.getField("name");
            //2.创建运行时类的对象
            PersonP p=(PersonP) clazz.newInstance();
            System.out.println(p);
            //3.将运行时类的指定的属性赋值
            name.set(p, "Jerry");
            System.out.println(p);
            
            System.out.println();
            
            //设置私有属性
            Field age=clazz.getDeclaredField("age");
            age.setAccessible(true);//设置为可访问
            age.set(p, 10);
            System.out.println(p);
        }
        
        //※通过反射调用运行时类的指定的方法
                @Test
                public void testGetMethod() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
                    Class clazz=PersonP.class;
                    Method m1=clazz.getMethod("show");
                    PersonP p=(PersonP) clazz.newInstance();
                    Object returnVa=m1.invoke(p);
                    System.out.println(returnVa);
                    
                    m1=clazz.getMethod("toString");
                    returnVa=m1.invoke(p);
                    System.out.println(returnVa);
                    //静态方法的调用
                    m1=clazz.getMethod("info");
                    m1.invoke(PersonP.class);//参数是类
                    
                    //获取运行时类中声明为private的方法
                    m1=clazz.getDeclaredMethod("display1", String.class,Integer.class);
                    m1.setAccessible(true);
                    Integer k=(Integer) m1.invoke(p, "Tom",15);
                    System.out.println(k);
                }
                
                
                
        //※通过反射调用运行时类的指定的构造器,创建运行时类的对象
                @Test
                public void testGetConstructor() throws NoSuchMethodException, SecurityException, InstantiationException, IllegalAccessException, IllegalArgumentException, InvocationTargetException{
                    Class clazz=PersonP.class;
                    Constructor c=clazz.getConstructor(String.class,int.class);
                    //c.setAccessible(true);
                    PersonP p=(PersonP) c.newInstance("罗伟",20);
                    System.out.println(p);
                }
        }

class PersonP extends Creater<String> implements Comparable,myInterface{
    public String name;
    private int age;
    int id;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public PersonP() {
        super();
        System.out.println("newInstance()调用了PersonP空参构造器");
    }
    public PersonP(String name, int age) {
        super();
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "Person [name=" + name + ", age=" + age + "]";
    }
    public void show(){
        System.out.println("我是一个人!");
    }
    public void display(String nation){
        System.out.println("我的国籍是:"+nation);
    }
    @Override
    public int compareTo(Object arg0) {
        // TODO 自动生成的方法存根
        return 0;
    }
    
    public static void info(){
        System.out.println("静态方法info!");
    }
    
    private Integer display1(String n,Integer i){
        System.out.println("private方法!");
        return i;
    }
    
}

class Creater<String>{
    double weight;
    public void breath(){
        System.out.println("呼吸!");
    }
}


interface myInterface extends Serializable{
    
}
TestConstructor
package com.btp.t4.Reflection;
//静态代理模式
//接口
interface ClothProduct{
    void productCloth();
}

//被代理类
class NikeClothFactory implements ClothProduct{

    @Override
    public void productCloth() {
        // TODO 自动生成的方法存根
        System.out.println("被代理类1开始执行!");
    }
    
}

//代理类
class ProxyFactory implements ClothProduct{

    ClothProduct cp;
    //创建代理类的对象时,实际传入一个被代理类的对象
    public ProxyFactory(ClothProduct cp){
        this.cp=cp;
    }
    @Override
    public void productCloth() {
        // TODO 自动生成的方法存根
        System.out.println("代理类开始执行!");
        cp.productCloth();
    }
    
}
public class TestClothProduct {
    public static void main(String[] args){
        NikeClothFactory fc=new NikeClothFactory();//创建被代理类的对象
        ProxyFactory proxy=new ProxyFactory(fc);//创建代理类的对象
        proxy.productCloth();
    }
}
TestClothProduct
package com.btp.t4.Reflection;

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

//动态代理的使用

interface Subject{
    void action();
}

//被代理类
class RealSubject implements Subject{

    @Override
    public void action() {
        System.out.println("被代理类执行!");
    }
    
}

class MyInvocationHandler implements InvocationHandler{
    Object obj;//实现了接口的被代理类的对象的声明
    //给被代理的对象实例化 ;返回一个同样实现了接口的代理类的对象
    public Object bind(Object obj){
        this.obj=obj;
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
    }
    //当通过代理类的对象发起对实现接口的被代理类的被重写的方法的调用时,都会转化为对下面的方法的调用
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("调用了实现InvocationHandler接口的实现类对象的invoke()方法!");
        Object returnVal=method.invoke(obj, args);//本例子中调用obj的action()
        return returnVal;
    }
    
}

public class TestProxy {

    public static void main(String[] args) {
        //1.创建被代理类的对象
        RealSubject real= new RealSubject();
        //2.创建一个实现了InvocationHandler接口的类的对象
        MyInvocationHandler mih=new MyInvocationHandler();
        //3.调用blind()方法,动态的返回一个同样实现了real所在类实现的接口Subject的代理类的对象
        Object obj=mih.bind(real);
        Subject sub=(Subject)obj;//此时的sub就是代理类的对象
        
        sub.action();//转到对InvocationHandler接口的实现类的invoke()的调用
    }

}
TestProxy
package com.btp.t4.Reflection;

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

interface Human{
    void info();
    void fly();
}
//被代理类
class SuperMan implements Human{

    public void info() {
        System.out.println("我是超人!");
    }

    public void fly() {
        System.out.println("我可以飞!");
    }
    
}

class HumanUtil{
    public void method1(){
        System.out.println("====方法1====");
    }
    public void method2(){
        System.out.println("====方法2====");
    }
}



class MyInvocationHandlers implements InvocationHandler{
    Object obj;//被代理类对象的声明
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        HumanUtil h=new HumanUtil();
        h.method1();
        
        Object returnVal=method.invoke(obj, args);
        
        h.method2();
        return returnVal;
    }
    
    public void setObject(Object obj){
        this.obj=obj;
    }
    
}

class MyProxy{
    //动态的创建一个代理类的对象
    public static Object getProxyInstance(Object obj){
        MyInvocationHandlers handler= new MyInvocationHandlers();
        handler.setObject(obj);
        
        return Proxy.newProxyInstance(obj.getClass().getClassLoader(),
                obj.getClass().getInterfaces(), handler);
    }
}

public class TestAOP {
    public static void main(String[] args){
        SuperMan man=new SuperMan();//创建一个被代理类的对象
        Object obj=MyProxy.getProxyInstance(man);
        Human hu=(Human)obj;
        
        hu.info();
        System.out.println();
        hu.fly();
        
    }
}
TestAOP
原文地址:https://www.cnblogs.com/a842297171/p/5206590.html