反射

反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并直接操作任意对象的内部属性和方法


图片.png

反射的功能
图片.png
java.lang.Class类的加载理解
1.类的加载过程:

程序经过javac.exe命令后,会生成一个或多个字节码文件(.class结尾);接着我们使用java.exe命令对某个字节码文件进行解释运行,相当于将某个字节码文件加载到内存中,此过程称为类的加载。加载到内存中的类,称为运行时类,此时运行时类,就作为Class的一个实例
2.换句话说,Class的实例就对应着一个运行时类
3.加载到内存中的运行时类,会缓存一定的时间。在此时间之内,可以沟通过不同方式获取此运行时类

获取Class的实例的方式(掌握三种)
public class ReflectPerson {
    @Test
    public void test01() throws ClassNotFoundException {
        //方式一:调用运行时类的属性,.class(掌握)
        Class<Person> clazz1 = Person.class;
        System.out.println(clazz1);

        //方式二:通过运行时类的对象,调用getClass()(掌握)
        Person p = new Person();
        Class<? extends Person> clazz2 = p.getClass();
        System.out.println(clazz2);

        //方式三:调用Class的静态方法,forName(String classPath)((掌握)使用频率高)
        Class<?> clazz3 = Class.forName("com.vv.reflect.Person");
        System.out.println(clazz3);

        System.out.println(clazz1 == clazz2);
        System.out.println(clazz3 == clazz2);

        //方式四:使用类的加载器,ClassLoader(了解)
        ClassLoader loader = ReflectPerson.class.getClassLoader();
        Class<?> clazz4 = loader.loadClass("com.vv.reflect.Person");
        System.out.println(clazz4);
    }
}
可以有Class对象的类型

举例:
Class对象的类型

类的加载过程
解释类的加载过程
类的加载过程举例

读取配置文件:

 @Test
    public void test01() throws IOException {
        Properties pro = new Properties();
        //读取配置文件方式一:默认当前project下
        //读取文件
        FileInputStream fis = new FileInputStream("src\\db1.properties");
        //加载文件
        pro.load(fis);

//        //读取配置文件方式二:文件默认识别为当前moudle的src下
//        InputStream is = Propeties01.class.getClassLoader().getResourceAsStream("db1.properties");
//        pro.load(is);

        String name = pro.getProperty("name");
        String age = pro.getProperty("age");
        System.out.println(name+"......"+age);
    }

通过反射运行时的类获得其属性、方法、构造器

@Test
    public void field() throws Exception {
        //1.创建Class的对象
        Class<Person> clazz = Person.class;
        //2.创建该对象的实例,便于调用对象的属性、方法、构造器
        Person person = clazz.newInstance();

        //3.获得该属性
        Field name = clazz.getDeclaredField("name");
        //4.保证当前属性是可访问的
        name.setAccessible(true);
        //5.获取、设置指定对象的此属性值
        name.set(person,"张三");
        System.out.println(name.get(person));
    }
    @Test
    public void method() throws Exception {
        Class clazz = Person.class;
        Person p = (Person) clazz.newInstance();
        Method declaredMethod = clazz.getDeclaredMethod("showTime",int.class);
        declaredMethod.setAccessible(true);
        //调用的invoke():参数1:方法的调用者  参数2:给方法形参赋值的实参
        // invoke()的返回值即为对应勒种调用方法的返回值
        Object o = declaredMethod.invoke(p, 12);
        System.out.println(o);

        System.out.println("**********");

        //静态方法的调用,不需要在进行创建对象
        Method staticTest = clazz.getDeclaredMethod("staticTest");
        staticTest.setAccessible(true);
        //调用的invoke方法没有返回值时,参数可以为null
        staticTest.invoke(clazz);// staticTest.invoke(null);

    }
    @Test
    public void constructor() throws Exception {
        Class clazz = Person.class;
        Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
        declaredConstructor.setAccessible(true);
        Object instance = declaredConstructor.newInstance("张三", 13);
        System.out.println(instance);
    }
反射的应用:动态代理
public class ProxyTest {

   @Test
   public void test(){
       Man man = new Man();
       Human proxyInstance = (Human) ProxyFactory.getProxyInstance(man);
       proxyInstance.breath();
       proxyInstance.eat("苹果");

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

   @Override
   public void breath() {
       System.out.println("Man呼吸新鲜空气");
   }

   @Override
   public void eat(String food) {
       System.out.println("Man吃"+food);
   }
}
/*
要想创建动态代理:
1.如何根据加载到内存中的被代理类,动态创建一个代理类及对象
2.当通过代理类的对象调用方法时,如何动态调用被代理类中的同名方法
*/
class ProxyFactory{

   //创建动态代理,
   //解决一:调用此方法,返回一个代理类对象Object;参数Object obj是被代理类的对象
   public static Object getProxyInstance(Object obj){
       //创建Handler对象
       MyInvocatoinHandler handler = new MyInvocatoinHandler();
       handler.bind(obj);
       //参数一:被代理类的类的加载器  参数二:被代理类的接口 参数三:调用代理类中的同名方法
       return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(),handler);
   }


}
//实现InvocationHandler接口
class MyInvocatoinHandler implements InvocationHandler{
   private Object obj;//需要使用被代理对象进行赋值
   public void bind(Object obj){
       this.obj = obj;
   };
   //Object proxy:动态代理的对象
   //Method method:调用的反射类中的方法
   //Object[] args:method中的参数
   //Object返回值类型是method方法中的返回值类型
   @Override
   public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       //被代理类的执行方法功能声明
       return method.invoke(obj,args);

   }
}
动态代理和AOP
图片.png
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容