java反射、函数式编程、注解

本文详细介绍了Java反射中Class对象的不同获取方式,包括Class.forName()、类名.class和对象.getClass(),并重点讲解了Class对象的功能,如暴力反射、获取构造方法和成员变量。此外,还涉及了函数式编程中的匿名内部类和Lambda表达式,以及注解的使用和元注解。
摘要由CSDN通过智能技术生成

反射笔记

java三阶段:

  • 1-源码
  • 2-class
  • 3-runtime

获取Class对象的方式

方式
Class.forName(“全类名”)将自己吗文件加载进内存,返回Class对象
多用于配置文件,将类名定义在配置文件中,读取文件,加载类
类名.class通过类名的属性class获取
多用于参数传递
对象.getClass()getClass()方法在 Object类中定义着
多用于对象的获取字节码的方式

结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个

Class对象功能

暴力反射

// 忽略访问权限修饰符的安全检查
Field/Constructor/Method对象.setAccessible(true) 

Declared 不考虑修饰符

获取构造方法/们

方法
Constructor<?>[] getConstructors()获取构造方法
Constructor getConstructor(类<?>… parameterTypes)获取指定参数的构造方法
Constructor getDeclaredConstructor(类<?>… parameterTypes)
Constructor<?>[] getDeclaredConstructors()
[操作]
T Construct对象.newInstance(Object… initargs)
T Class对象.newInstance()空参数构造方法创建对象可这样简化

T表示返回对象类型

获取成员变量/们

方法
Field[] getFields()获取所有public修饰的成员变量
Field getField(String name)获取指定名称的public修饰的成员变量
Field[] getDeclaredFields()获取所有的成员变量,不考虑修饰符
Field getDeclaredField(String name)获取指定名称的,不考虑修饰符
[操作]
void set(Object obj, Object value)设置值
Object get(Object obj)获取值

获取成员方法/们

方法
Method[] getMethods()获取public修饰的所有方法
Method getMethod(String name, 类<?>… parameterTypes)name 方法名称
parameterTypes 参数类型列表
Method[] getDeclaredMethods()
Method getDeclaredMethod(String name, 类<?>… parameterTypes)
[操作]
Object invoke(Object obj, Object… args)执行方法
参数obj:方法类的对
参数args:方法参数列表
String getName()获取方法名称

获取全类名

String getName()

函数式编程

通过匿名内部类和lambda表达式完成

匿名内部类:

定义一个接口,该接口定义一个未实现的方法,当其他类方法参数用到该接口类型时,可以直接new该接口并实现方法即可。

Lambda表达式:

当某个方法需要一个参数,这个参数类可以是一个接口并且接口只有一个方法时可用Lambda。

  • 一些参数
  • 一个箭头
  • 一段代码

格式:(参数列表)->{一些重写方法的代码};
可省略内容:

  • 括号中参数列表的数据类型,可省略
  • 括号中的参数如果只有一个,那么类型和括号都可以省略
  • 如果{}中代码只有一行,无论是否有返回值,都可以省略({},return,分号)
    • 注意:要省略{},return,分号必须一起省略

**两者实现都是:**定义一个接口,接口只定义一个方法,

  • 直接创建接口并重写方法作为参数传入需要相应类型参数的方法中
  • 匿名内部类需要重写方法和方法体,

**区别:**Lambda表达式更加简洁一些,在Lambda表达式中不需重写方法,

Lambda引用

可以简化lambda表达式来简化代码

  • 使用前提是对象名是已经存在的,成员方法也存在

执行过程

  • 创建函数式接口–>lambda实现接口方法–>普通方法调用接口方法

【方法引用】

@FunctionalInterface // 函数式接口
interface Printabe{
    public void print(String str);
}

// 普通方法
public static void printString(Printabe p) {
    p.print("helloword");
    // 这里p调用的print("helloword")即等于调用了arg->System.out.println(arg)
    // "helloword"赋值给参数arg,方法体System.out.println(arg)打印了arg(即helloword)出来
}

public static void main(String arg[]){
    // Lambda表达式实现
    // p即print()方法的参数str,System.out.println(arg)即相当于该方法的方法体
    printString(p->System.out.println(arg));  
    
    // 引用实现
    printString(System.out::println); 
}

【定义类对象引用方法】

public static void main(String arg[]){
    // Lambda表达式实现
    printString((s)->{
        // 创建对象
        t05_1MethodRerObj_方法引用 obj = new t05_1MethodRerObj_方法引用();
        obj.printUpperCaseString(s);
    }); 
    // 引用实现
    t05_1MethodRerObj_方法引用 obj = new t05_1MethodRerObj_方法引用();
    printString(obj::printUpperCaseString);
}

【类名引用静态方法】

// 函数式编程所需接口
@FunctionalInterface
interface Calcable{
    public int calsABs(int number);
}

//使用方法
public static int method(int number,Calcable c) {
    return c.calsABs(number);
}

public static void main(String arg[]){
	//  Lambda表达式实现
	int numberabs = method(-10, (n)->{
		return Math.abs(n);  // 这里相当于calsABs的方法体
	});
    
	// 引用实现
	int numberabs2 = method(-10, Math::abs);
}

【super引用父类方法】

super::父类方法名

【this引用本类方法】

this::本类方法名

【类引用构造方法】

// 函数式编程所需接口
@FunctionalInterface
interface PersonBuilder{
   builPerson(String name);
}

//定义一个方法,参数传w递姓名和PsesonBuilder接口,方法中通过姓名创建Person对象
public static void printName(String name,PersonBuilder pb) {
    Person person = pb.builPerson(name);
    System.out.println(person);
}

// lambda表达式实现
printName("迪丽热巴", (String name)->{
		return new Person(name); //这里相当 于builPerson的方法体
	}
);
// 引用实现
//创建对象已知,new
//使用Person类的带参构造方法,通过传递的姓名创建对象
printName("古力娜扎", Person::new);


// 例子2:创建数组------------------------------------------------
// 函数式编程所需接口
@FunctionalInterface
interface AarryBuilder{
    // 定义一个创建int类型数组的方法,参数传递数组场地,返回创建好的int类型数组
    int[] builderAray(int length);
}

// 创建方法
public static int[] CreateArray(int length,AarryBuilder ab) {
	return ab.builderAray(length);//该语句相当于使用了lambda表达式内分方法体
}

// lambda表达式
CreateArray(10, (len)->{//第二参数相当于实现接口方法便于创建方法调用该方法
	return new int[len];
});

// 引用实现
// int[]引用new 根据参数传递的长度来创建数组
CreateArray(10,int[]::new);

注解

**相关命令用到注解:**javadoc–生成文档 javap–反编译

  • jdk1.5后新特性
  • 说明程序的
  • 定义注解–@interface
  • 使用注解–@注解名称

注解本质 就是一个接口,默认继承annotation接口

jdk预定义注解

  • @Override :检测被该注解标注的方法是否继承自父类(接口)
  • @Deprecated :表示该注解标注的内容已过时
  • @SuppressWarnings :压制警告

自定义注解 属性:接口中的抽象方法 其返回值类型有如下:

  • 基本数据类型
  • String
  • 枚举
  • 注解
  • 以上类型数组

定义属性 使用default关键字给属性赋初始值 使用注解时有默认值的属性可不赋值
使用注解时 只赋值一个属性且属性名叫value则value可省略
数组赋值 值用{}包裹,单个值{}可省

元注解:描述注解的注解

  • @Target 描述注解能够作用位置
    • ElementType.TYPE 表示只能作用到类上
    • ElementType.METHOD 可以作用到方法上
    • ElementType.FIELD可以作用到成员变量上
  • @Retention 描述注解被保留的阶段
    • RetentionPolicy.RUNTIME 被描述的注解会保留到class字节码文件中被jvm读取到
  • @Documented 描述注解是否被抽取到api文档中
  • @Inherited 描述注解是否被子类继承
解析注解 获取属性中定义的属性值
  • 获取加了注解的类字节码class文件对象 即.class等

  • 获取注解对象

    // 其实就是在内存中生成了一个该注解接口的子类实现对象
    字节码文件对象.getAnnotation(注解字节码 即注解名.class)  
    
  • 调用注解对象中定义的抽象方法(即注解的属性)获取属性值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值