Java基础 -- 05反射reflect

目录

引序 

说不通1:注解

说不通2:匿名内部类

说不通3:动态代理

反射:

反射定义 

强调:类对象

又强调:static 类静态成员

再三强调:synchronized 修饰符

类对象:知晓类结构

类结构之:内部成员

内部成员--构造函数

内部成员--数据成员

内部成员--方法成员

静态代理:

动态代理:

反射 + 注解

反射 + 泛型 + 注解

getGenericSuperclass()用法


引序 

引序:开始反射概念学习之前,先来段引序。

请牢记:计算机的三大程序结构;顺序执行结构、条件分支结构、循环处理结构。

有时我们写的程序会自我感觉这里写了代码,它是怎么被调度执行的呢,按照程序的顺序执行来考究,有点说不通。我举几个例子说明看起来说不通的现象:

  • 说不通1:注解

import java.lang.reflect.*;
import java.lang.annotation.*;
 
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno{	                                    // 注解定义
    String name() default "12345";
    int value();
}
 
@MyAnno(name="haha",value=123)                          // 注解钉点
class B {
 
    public static void main(String[] args){
		
	if( B.class.isAnnotationPresent(MyAnno.class) ){
	    Annotation annos[] = B.class.getAnnotations();  // 消费注解
	    for(Annotation anno : annos){
		System.out.println(anno);
		System.out.println( ((MyAnno)anno).name() );
		System.out.println( ((MyAnno)anno).value() );
        System.out.println( anno.annotationType().getName() );
}}}}

上面注解的小示例:如果看《注解定义》《注解钉点》 这两个地方,能搞懂我们写这两处的意思嘛?完全是懵圈的,这是什么代码,又什么时候被调度执行,咋执行的呢?正是因为有 《注解消费》 这个梗,我们才恍然大悟,注解是啥时用起来的。(这也是很多框架利用大量注解的底层技术手段,第三方框架有其自己的《注解定义》以及《注解消费》底层,开放给我们开发时用的就是“注解钉点”,我们利用好《注解钉点》这一点就OK


  • 说不通2:匿名内部类

匿名内部类:作为方法的入参来使用,例如:

1:事件监听处理器类:处理事件时作为监听处理器方法的形参的Handler类

event.addEventListener( new Handler() { //这里的Handler就是匿名内部类

    public void xxxMethed(Event event){ //这是匿名类中的方法xxxMethod();
    }

}); //这个xxxMtd()是由事件调度线程来执行的。

以上代码我们只是调用了addEventListener(Handler hd); 传进来一个hd对象而已,那么Handler类中的xxxMethod()方法怎么会被调用的呢?答:是被事件调度线程来执行的。事件调度线程是JVM管理的,不受我们的代码控制。

2:多线程编程时的任务类:往线程池当中提交一个实现了Runnable接口的类

threadPoolExecutor.execute( new Runnable() { // Runnable是匿名内部类

    public void run(){ }                    // 匿名类中的方法run();    

}); // 这个run()是由线程池调度工作线程来执行的。

以上代码只是调用了execute(Runnable task); 传进来一个task任务而已,那么Runnable类中的run()方法怎么会被调用的呢?答:是被线程池调度工作线程来执行的。线程池是一个框架,它怎么调度和管理工作线程,不受我们的代码控制。我们“写好匿名内部类中的方法业务逻辑”这一点就OK理解匿名内部类很重要,它是静态代理模式的一种体现。之所以匿名内部类很重要,是因为它是理解lambda函数式编程思想的基础。


  • 说不通3:动态代理

import java.lang.reflect.*;

//接口
interface InterfaceHello {
    void sayHello();
    void read();
}

//业务类:实现接口
class HelloImpl implements InterfaceHello {
    public void sayHello() {
        System.out.println("hello world");
    }
    public void read() {
        System.out.println("I am reading...");
    }
}

//我是代理:业务类真正业务逻辑的前后,我搞点事(比如:打个广告)
class ProxyHello implements InvocationHandler{

    private Object target;

    public ProxyHello(Object target) {
        this.target=target;
    }

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {

        System.out.println("我是代理,看视频之前我打个广告,haha!");

        Object obj = method.invoke(target,args); // 真正的业务逻辑

	    System.out.println("我是代理,视频看完给评价下呗,多谢!\r\n");
        
        return obj;
    }
}

//测试
public class HelloTest {

    public static void main(String[]args) {
 
        try{
	        InterfaceHello h = (InterfaceHello)Proxy.newProxyInstance(
		        HelloTest.class.getClassLoader(),
                new Class[]{InterfaceHello.class},
                new ProxyHello(new HelloImpl())
	        );
        
	        h.sayHello(); // 调用InterfaceHello接口中的sayHello()方法
	        h.read();     // 调用InterfaceHello接口中的read()方法
	    }
	    catch(Exception e){}
    }
}

程序输出:

我是代理,看视频之前我打个广告,haha!
hello world
我是代理,视频看完给评价下呗,多谢!

我是代理,看视频之前我打个广告,haha!
I am reading...
我是代理,视频看完给评价下呗,多谢!

如果单看以上的测试类:h.sayHello(); 这句代码,是蒙圈的,因为按照我们以往的程序经验,这不就是实现了InterfaceHello接口的HelloImpl干的事嘛,但是程序的输出却不是这样,前有广告,中间是正事,后有评论。为什么这样呢?是因为:h是Proxy.newProxyInstance()出来的,下面简要分析下:

Proxy.newProxyInst

你可能感兴趣的:(Java基础,Java基础,反射,reflect,Proxy,动态代理)