20、Java——反射,注解与lambda表达式

 31、反射:

User类

 

(1)发生在程序运行期间的动态机制|行为,是java的唯一动态机制-->反射机制。

​ (2)Java反射机制,可以实现以下功能:

        a.在运行时判断任意一个对象所属的类;

        b.在运行时构造任意一个类的对象;

        c.在运行时判断任意一个类所具有的成员变量和方法;

        d.在运行时调用任意一个对象的方法;

        e.生成动态代理;

①反射的源头:

Class<T> Class类型的实例可以用来表示java中运行期间的一个类型,Class对象。

②Class对象在类第一次加载到内存后就已经存在的,唯一的,不变的,每一个类型只有一个,Class对象可以操作这个类的所有内容(属性方法构造器...)。

③如何获取反射的源头:Class对象。

a.类名.class

b.Class.forName(权限定名)  权限定名:包名.类名   -->推荐。

c.对象.getClass()

(3)反射操作构造器

①构造器<T> getConstructor(类<?>... parameterTypes) 返回一个 构造器对象,该对象反映此 类对象所表示的类的指定公共构造函数。

②构造器<?>[] getConstructors() 返回一个包含 构造器对象的数组, 构造器对象反映了此 类对象所表示的类的所有公共构造函数。

③以上都是获取公共的,被public修饰的构造器

        a.构造器<T> getDeclaredConstructor(类<?>... parameterTypes) 返回一个 构造器对象,该对象反映此 类对象所表示的类或接口的指定构造函数。

        b.构造器<?>[] getDeclaredConstructors() 返回 构造器对象的数组, 构造器对象反映由此 类对象表示的类声明的所有构造函数。

反射创建对象

        a.Class-->T newInstance()  默认调用类型的空构造为对象初始化信息  -->不推荐使用

b.不能确定一个类型是否存在空构造,极有可能遇到运行时异常Constructor---> T newInstance(Object... initargs) 创建对象的同时调用当前构造器为对象初始化信息

(4)①反射操作属性

        a.字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。

        b.字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。

        c.字段 getDeclaredField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定声明字段。

        d.字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。

e.void set(Object obj, Object value) 将指定对象参数上此 字段对象表示的字段设置为指定的新值。

f.Object get(Object obj) 返回指定对象上此 字段表示的字段的值。

②反射操作方法

        a.方法 getMethod(String name, 类<?>... parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定公共成员方法。

        b.方法[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。

        c.方法 getDeclaredMethod(String name, 类<?>... parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定声明方法。

        d.方法[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象表示的类或接口的所有已声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承的方法。

e.Object invoke(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法。

(5)反射操作数组

①static Object newInstance(类<?> componentType, int length) 创建具有指定组件类型和长度的新数组。

②static Object get(Object array, int index) 返回指定数组对象中索引组件的值。

③static void set(Object array, int index, Object value) 将指定数组对象的索引组件的值设置为指定的新值。

   反射常用方法

2、注解 : Annotation

(1)标注,java8引入的注解机制

①作用:

a.注释,b.标志|标识,c.使用注解时可以传递参数,可以在程序中通过反射操作注解,获取配置的信息在程序中使用,d.可以存在于Class文件中,e.大量的代替|简化配置文件的使用

②使用:@注解名(参数)

③注解的分类:

a.jdk的内置注解 : 常见

b.@Override 检查重写方法

c.@SuppressWarnings("all") 抑制警告

d.@Deprecated 表示已过时,不推荐使用

e.@FunctionalInterface 标识函数式接口

④参数的个数分类:a.标志|标识注解b.单值注解c.完整注解d.元注解 : 注解注解的注解e.自定义注解。

(2)元注解 : 就是负责注解其他注解

①@Target 用于描述注解的使用范围

②@Retention 规定注解类型的声明周期

③@Documented 保留在API文档中

④@Inherited 标识注解类型可以被继承

(3)自定义注解

①@interface 定义注解类型

②默认实现java.lang.annotation.Annotation接口

③自定义的注解类型就不能显示的继承其他父类,实现其他接口

④如果注解类中的属性只有一个,建议名字为value,为value属性赋值可以直接赋值

⑤为注解类型定义属性|字段: 数据类型 数据名();

⑥属性的数据类型要求为: 基本数据类型 String, 枚举 , 注解类型 , 以及以上类型的数组

⑦属性可以通过default提供默认值

(4)注解解析器 : 通过反射操作注解

①案例: 自定义水果清单 FruitList,int apple;int pair;为每种水果提供一个默认的进货数量,通过注解进行配置,注解类型: FruitNum  属性: int value();

②注意:如果通过反射操作注解,注解类型的生命周期应该定义为运行期

3、Lambda表达式

注解解析器 : 通过反射操作注解员工类(Emplyee)

    (1)题一:调用Collections.sort()方法,通过定值排序比较两个Employee(先按年龄比,年龄相同按姓名比),使用Lambda作为参数传递

  分析:

    ①定制排序:指自定义比较器|定制排序,自然排序:内部比较器|自然排序

    ②先比较年龄,年龄相同才比较姓名

(2)习题二:

      ①声明函数式接口,接口中声明抽象方法,public String getValue(String str)

      ②声明类 TestLambda,类中编写方法使用接口作为参数,讲一个字符串转成大写,并作为方法的返回值

     ③再将一个字符串的第2个和第4个索引位置进行截取子串

 

lambda : 就是把行为作为参数传递,函数式接口作为形参,lambda表达式作为实参,传递行为

(3)习题三:

      ①声明一个带两个泛型的函数式接口,发型类型为<T,R> T为参数,R为返回值

②接口中声明对应抽象方法

③在TestLambda类中声明方法,参数三个,两个long类型的参数,接口作为参数,接口实现中计算两个long型参数的和

④再计算两个long型参数的乘积

(4)函数式接口

接口中只与一个必须被重写的抽象方法,@FunctionalInterface

      ②四大内置函数式接口:

a.消费型接口  Consumer<T>

            void accept(T t)   --> 有来无回,有参数没有返回值

b.供给型接口  Supplier<T>

            T get()

c.函数型接口  Function<T,R>

            R apply(T t)

d.段言型接口  Predicate<T>

            boolean test(T t)


posted @ 2021-07-26 16:46  孤影_空白  阅读(262)  评论(0编辑  收藏  举报