泛型与反射
泛型:
在定义类方法时声明一个泛型比如<E>来代表任意一个类型
定义:
在类中声明,在整个类中都可以直接使用
作用:
1、保证数据类型的安全 避免出现类型转换异常(ClassCastException)
2、规范类型/集合:
set 和map的关系:
Hashtable:
反射:
什么是反射?
它允许程序在运行时访问、检查和修改自身内部结构。通过反射,我们可以获取类的信息(如类名、方法、属性等),创建对象,调用方法和设置属性值等。
什么是类对象?
类对象是用来记录获取 类中定义的属性和方法、构造方法的对象
怎样获取类对象?
·通过类名.class
·通过对象.getClass()获取
·通过Class.forName(“类的全名”)方法
方法:
getMethod(“方法名”,参数列表):
获取能够访问到的public方法
getMethods():
获取所有能访问到的public方法的数组
getDeclaredMethods(“方法名”,参数列表):
获取定义在该类中的方法
invoke:
传递指定的参数
构造方法:newInstance()
·怎样获取属性?
Filed -----描述属性
getField(“属性名”):
获取该类中能访问到的public属性(包含父类、父接口)
getFields(“属性名”):
获取该类中所有能访问到的public属性
getDeclaredField(”属性名”):
获取定义在该类中属性
getDeclaredFields(”属性名”):
获取所有定义在该类中的属性
setAccressible():
可以破坏属性的封装性
可以对没有访问权限的属性进行设置
set(obj,val):
通过field设置某一对象的属性值
get(obj):
获取obj对象的属性值
怎样获取方法?
getConstructor():
通过参数列表获取指定的public构造方法
getConstructors():
获取所有的public方法
getDeclaredConstructor():
通过参数列表获取构造方法
getDeclaredConstructors():
获取所有的构造方法
判断修饰符:
getModifiers()的Modifier.is……..方法:
获取父类和父级接口:
每个类只有一个类对象:
创建对象的方式?
1、new
2、反序列化
3、克隆
4、反射
Lambda表达式
介绍
Java8引入了lambda表达式Lambda 表达式(lambda expression)是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数。Lambda表达式同时还提升了对集合、框架的迭代、遍历、过滤数据的操作。
什么是函数式接口
只有一个 抽象方法 (Object类中的方法除外)的接口是函数式接口。
注意:
只能有一个抽象方法,没有抽象方法或者有多个抽象方法的接口都不是函数式接口。
必须是抽象方法,如果接口里面只有一个静态方法或者default方法,都不是函数式接口。
如果接口里面只有一个抽象方法,但是这个抽象方方法是Object类中的方法,如hashCode,equals方法,这个接口也不是函数式接口。
如果是函数式接口,可以添加@FunctionalInterface注解,不是函数式接口的接口添加该注释,编译器会报错。
Lambda表达式语法
lambda表达式分为三部分,方法参数、lambda操作符和函数式接口方法的实现逻辑。()里面参数的个数,根据函数式接口里面抽象方法的参数个数来决定。当只有一个参数的时候,()可以省略当expr逻辑非常简单的时候,{}和return可以省略
常见的函数式接口
Runable/Callable<V>/Comparator<T>
java.util.function包下的一系列函数式接口
Supplier 代表一个输出
Consumer 代表一个输入
BiConsumer 代表两个输入
Function 代表一个输入,一个输出(一般输入和输出是不同类型的)
UnaryOperator 代表一个输入,一个输出(输入和输出是相同类型的)
BiFunction 代表两个输入,一个输出(一般输入和输出是不同类型的)
BinaryOperator 代表两个输入,一个输出(输入和输出是相同类型的)
Lambda表达式之方法引用
方法引用是用来直接访问类或者实例的已经存在的方法或者构造方法,方法引用提供了一种引用而不执行方法的方式,如果抽象方法的实现恰好可以使用调用另外一个方法来实现,就有可能可以使用方法引用
方法引用的分类
静态方法的引用
如果函数式接口的实现恰好可以通过调用一个静态方法来实现,那么就可以使用静态方法引用语法: 类名::staticMethod(方法名)
Consumer<Integer> c1 = a -> System.out.println(a);
Consumer<Integer> c2 = a -> lambda02.fun(a);
Consumer<Integer> c3 = lambda02::fun;
实例方法引用
如果函数式接口的实现恰好可以通过调用一个实例的实例方法来实现,那么就可以使用实例方法引用语法: inst(实例名)::instMethod(方法明)
Consumer<Integer> c1 = a -> System.out.println(a);
Consumer<Integer> c2 = a -> new lambda03().fun(a);
Consumer<Integer> c3 = new lambda03()::fun;
对象方法引用
抽象方法的第一个参数类型刚好是实例方法的类型,抽象方法剩余的参数恰好可以当做实例方法的参数。如果函数式接口的实现能由上面说的实例方法调用来实现的话,那么就可以使用对象方法引用语法: 类名::instMethod
Inter i = Foo::foo2;interface Inter {void test(Foo a, String b);}
构造方法引用
如果函数式接口的实现恰好可以通过调用一个类的构造方法来实现,那么就可以使用构造方法引用类名::new
Supplier<Thread> S3 = Thread::new;
Supplier<List> s4 = ArrayList::new;
Supplier<Map> s5 = HashMap::new;