一、反射获取成员变量
方法:
测试代码:
学生类
package com.qf.test.test01;
public class Student {
private String name;
private String hobbey;
public int age;
public static void show1(){
System.out.println("班长洗脚");
}
public void show(){
System.out.println(name+age+hobbey);
}
}
测试类
package com.qf.test.test01;
import org.junit.Test;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test01 {
@Test
public void show01() throws ClassNotFoundException {
//获取Class对像
Class<?> name = Class.forName("com.qf.test.test01.Student");
//获取全部公有的成员变量
Field[] fields = name.getFields();
//循环遍历
for(Field f:fields){
System.out.println(f);
}
}
@Test
public void show02() throws ClassNotFoundException {
//获取Class对像
Class<?> name = Class.forName("com.qf.test.test01.Student");
//获取全部的成员变量 包括私有的
Field[] fields = name.getDeclaredFields();
//循环遍历
for(Field f:fields){
System.out.println(f);
}
}
@Test
public void show03() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
//获取Class对像
Class<?> name = Class.forName("com.qf.test.test01.Student");
//获取单个 公有的成员变量
Field field = name.getField("age");
//实例化对象
Object o = name.newInstance();
//给成员变量赋值
field.set(o,21);
//获取获取值
System.out.println(field.get(o));
}
@Test
public void show04() throws IllegalAccessException, InstantiationException, ClassNotFoundException, NoSuchMethodException, InvocationTargetException {
//获取类对象
Class<?> name = Class.forName("com.qf.test.test01.Student");
//实例化对象
Object o = name.newInstance();
//获取静态方法
Method method = name.getMethod("show1");
//调用方法
method.invoke(o);
}
@Test
public void show05() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
//获取Class对像
Class<?> name = Class.forName("com.qf.test.test01.Student");
//获取单个 公有的成员变量
Field field = name.getDeclaredField("name");
//使用暴力反射去取私有化
field.setAccessible(true);
//实例化对象
Object o = name.newInstance();
//给成员变量赋值
field.set(o,"班长");
//获取获取值
System.out.println(field.get(o));
}
}
二、函数型接口
简介:
概念:接口中可以有其他方法,但只能有一个抽象方法
注解:@FunctionalInterface 用于检查是否是函数型接口
函数型接口两种体现 :A.函数型接口作为方法的参数 B.函数型接口作为方法的返回值
函数型接口作为方法的参数:
package com.qf.test.test02;
public interface Inner1 {
void show();
}
package com.qf.test.test02;
public class Test01 {
public static void main(String[] args) {
showInfo(()-> System.out.println("班长去洗脚"));
}
public static void showInfo(Inner1 inner1){
inner1.show();
}
}
函数型接口作为方法的返回值:
package com.qf.test.test02;
public interface Inner2 {
void show();
}
package com.qf.test.test02;
public class Test02 {
public static void main(String[] args) {
show1().show();
}
public static Inner2 show1(){
return ()-> System.out.println("班长洗脚");
}
}
三、jdk8提供的四种函数型接口
1.Supplier-供给型接口
方法: T get() 得到一个结果
测试:
package com.qf.test.test03;
import java.util.Arrays;
import java.util.function.Supplier;
public class Test01 {
public static void main(String[] args) {
String s= getSer(()->"班长洗脚".substring(2));
System.out.println(s);
int m = getMax(()->{
int [] nums = {20,54,31,84,10,89,41,21};
Arrays.sort(nums);
int max = nums[nums.length-1];
return max;
});
System.out.println(m);
}
//获取字符串后两位
public static String getSer(Supplier<String > sup){
return sup.get();
}
//获取数组中最大值
public static int getMax(Supplier<Integer> sup){
return sup.get();
}
}
2.Consumer-消费型接口
测试:
package com.qf.test.test04;
import java.util.function.Consumer;
public class Test01 {
public static void main(String[] args) {
show("班长洗脚",s -> System.out.println(s.substring(2)));
show2("ABCdef",s -> System.out.println(s.substring(0,3).toLowerCase()),
s -> System.out.println(s.substring(3).toUpperCase()));
String [] arrays = {"迪丽热巴:25","古力娜扎:25"};
show3(arrays,s ->{
String[] strings = s.split(":");
System.out.print("名字:"+strings[0]+",");
},s -> {
String[] split = s.split(":");
System.out.println("年龄:"+split[1]);
});
}
//获得字符串后两位
public static void show(String s, Consumer<String > con){
con.accept(s);
}
//将字符串截取后转换为大小写
public static void show2(String s,Consumer<String> con1,Consumer<String> con2){
con1.andThen(con2).accept(s);
}
//将字符串分隔
public static void show3(String [] arrays,Consumer<String> con1,Consumer<String> con2){
for (String s:arrays){
con1.andThen(con2).accept(s);
}
}
}
3.Predicate-断言型接口
测试:
package com.qf.test.test05;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
public class Test01 {
public static void main(String[] args) {
/*boolean f = isFlag("班长洗脚",s -> s.length()>5);
System.out.println(f);*/
/* boolean f = isFlag("班长洗脚",s -> s.length()>3,s -> s.contains("洗脚"));
System.out.println(f);*/
List<String> list=isFlag(new String[]{"迪丽热巴","古力娜扎","欧阳娜娜","杨迪"},s -> s.length()==4,s -> s.contains("迪"));
System.out.println(list);
}
public static boolean isFlag(String s, Predicate<String> per1){
return per1.test(s);
}
public static boolean isFlag(String s,Predicate<String> per1,Predicate<String> per2){
//return per1.and(per2).test(s);
//return per1.or(per2).test(s);
return per1.negate().test(s);
}
public static List<String> isFlag(String [] array,Predicate<String> per1,Predicate<String> per2){
List<String> list = new ArrayList<>();
for (String s:array){
//判断是否满足条件
if (per1.and(per2).test(s)){
//存入集合
list.add(s);
}
}
return list;
}
}
4.Function-转换型接口
package com.qf.test.test06;
import java.util.function.Function;
public class Test01 {
public static void main(String[] args) {
int in = show("123", s -> Integer.parseInt(s));
System.out.println(in);
String s1 = show("1233", s -> Integer.parseInt(s), integer -> integer + "");
System.out.println(s1.charAt(1));
}
public static int show(String s, Function<String,Integer> fun){
return fun.apply(s);
}
public static String show(String s,Function<String,Integer> fun1,Function<Integer,String> fun2){
return fun1.andThen(fun2).apply(s);
}
}
四、Stream流
简介:
Stream是一个接口,主要用于对数据进行过滤
Stream提供了两种类型方法:
A.延迟方法:使用Stream流的方法之后 返回的还是Stream流对象 可以继续使用其方法
B.终结方法:使用Stream流的方法之后 返回的不是Stream流对象 不可以继续使用其方法
获取Stream对象:
Stream 常用的方法:
测试:
package com.qf.test.test07;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Stream;
public class Test01 {
public static void main(String[] args) {
/* List<String> list = new ArrayList<>();
list.add("迪丽热巴");
list.add("欧阳娜娜");
list.add("古力娜扎");
list.add("杨幂");
list.add("刘诗诗");
list.add("高圆圆");
list.stream().filter(s -> s.length()==4).forEach(s -> System.out.println(s));*/
Stream stream = Stream.of(10, 20, "迪丽热巴", "欧阳娜娜", "古力娜扎", 20.5, 'c');
//截取前3个元素
//stream.limit(3).forEach(s-> System.out.println(s));
//返回元素个数
//System.out.println(stream.count());
//跳过前2个元素
//stream.skip(2).forEach(s-> System.out.println(s));
//拼接
Stream.concat(stream.limit(3),Stream.of(33)).forEach(s-> System.out.println(s));
}
}
案例:
需求:
分析:
代码:
Preson类:
package com.qf.test.test08;
public class Person {
private String name;
public Person() {
}
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
'}';
}
}
测试类:
package com.qf.test.test08;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class Test01 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
list1.add("宫本武藏");
list1.add("宋公明");
list1.add("苏有朋");
list1.add("石头人");
list1.add("时传祥");
list1.add("李耳");
list1.add("庄子");
list1.add("洪七公");
List<String> list2 = new ArrayList<>();
list2.add("帕瓦罗蒂");
list2.add("张三丰");
list2.add("赵薇薇");
list2.add("张自忠");
list2.add("波尔只听铁木真");
list2.add("张天爱");
list2.add("张翠花");
List<Person> list = Stream.concat(list1.stream().filter(s -> s.length() == 3).limit(3),
list2.stream().filter(s -> s.substring(0, 1).equals("张")).skip(2)).map(Person::new).collect(Collectors.toList());
System.out.println(list);
}
}
五、注解
简介:
注释:用于对代码的解释说明, 主要提供给程序员看的
注解:用于对代码的解释说明, 主要是提供给jvm来进行识别的
本质:
注解本质就是一个接口
定义:
注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与 类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对 这些元素进行说明,注释。
a.注解又称为元数据 b.在jdk1.5后引入 c.可以对以上元素进行说明,注释
作用:
A.编写文档:通过代码里标识的元数据生成文档【生成文档doc文档】
B.代码分析:通过代码里标识的元数据对代码进行分析【使用反射】
C.编译检查:通过代码里标识的元数据让编译器能够实现基本的编译检查【Override】
jdk提供的三个注解:
A.@Override 用于标注是否是重写的方法
B.@Deprecated 用于表示是否是过时的方法
例如: stop() 过时的方法是可以使用 不提倡使用过时的方法
C.SuppressWarnings 用于压制黄色的警告线
说明:: a.定义类上 b.定义在方法上 c.定义在属性
@SuppressWarnings("all") 定义在类上 表示压制所有黄色的警告
自定义注解:
格式:
1.元注解(写在注解上面)
2.注解的属性(注解的抽象方法)
注解的成员:
A.静态的常量(不关注) B.抽象方法(关注)==注解中的抽象方法也称为是属性
注解中抽象方法的返回值类型:
A.基本数据类型 四类八种
B.字符串类型 String
C.枚举类型
D.注解类型
E.以上类型的数组类型
注意点:
使用注解的时候,必须给注解的所有属性赋值
如果注解的属性设有默认值,使用注解时可以不用给该属性赋值
如果注解的属性是数组类型的,使用注解时 可以使用大括号 赋予多个值
如果注解的属性是数组类型的,使用注解时 可以使用小括号 赋一个值
如果注解的属性只有一个 且 属性名为 value 使用注解时可以不用为其赋值
例子:
package com.qf.test.test09;
public @interface MyAnno {
/**
* 注解的抽象方法称为 注解的属性
* 注解的属性类型只能有以下五种类型
* 1.基本数据类型 四类八种:整数型:byte、short、int、long 小数型:float、double 字节型:char 布尔型:boolean
* 2.字符串类型 String
* 3.枚举型
* 4.注解型
* 5.以上四种类型的数组类型
*/
int age();
double sum() ;
char c();
boolean b() default false;//表示默认值为false
String name() default "阿甘";//这样表示 name的默认值为阿甘
char[] cc();
}