• 笔记1-2:java反射、函数式编程、注解


    反射笔记

    java三阶段:1-源码 2-class 3-runtime

    一. 获取Class对象的方式

    ---【获取Class.forName("全类名")】:将自己吗文件加载进内存,返回Class对象
          多用于配置文件,将类名定义在配置文件中,读取文件,加载类
    ---【类名.class】:通过类名的属性class获取
          多用于参数传递
    ---【对象.getClass()】:getClass()方法在 Object类中定义着
          多用于对象的获取字节码的方式
    结论:同一个字节码文件(*.class)在一次程序运行过程中,只会被加载一次,不论通过哪一种方式获取的Class对象都是同一个
    

    二. Class对象功能

    1. 暴力反射    Field/Constructor/Method对象.setAccessible(true)==忽略访问权限修饰符的安全检查
    2.【获取成员变量/们】
          Field[] 	getFields()                      获取所有public修饰的成员变量
          Field 	getField(String name)            获取指定名称的public修饰的成员变量
          Field[] 	getDeclaredFields()              获取所有的成员变量,不考虑修饰符
          Field 	getDeclaredField(String name)    获取指定名称的,不考虑修饰符
          [操作]
                设置值		void 		set(Object obj, Object value)  
                获取值		Object值 	get(Object obj) 
    		
    3.【获取构造方法/们】
          Constructor<?>[] getConstructors()  
          Constructor<T> 	getConstructor(类<?>... parameterTypes)  
          Constructor<T> 	getDeclaredConstructor(类<?>... parameterTypes)  
          Constructor<?>[] getDeclaredConstructors()  
          [操作]
                创建对象      T表示返回对象类型
                T    Construct对象.newInstance(Object... initargs)  
                T    Class对象.newInstance()(空参数构造方法创建对象可这样简化)
    		
    4.【获取成员方法/们】
          Method[] getMethods()  
          Method     getMethod(String name, 类<?>... parameterTypes)  
                name==方法名称	parameterTypes==参数类型列表
          Method[]    getDeclaredMethods()  	
          Method     getDeclaredMethod(String name, 类<?>... parameterTypes)  
          [操作]
                执行方法	       Object invoke(Object obj, Object... args)  
                      参数:obj==方法类的对象    args==方法参数列表
                获取方法名称    String getName()
    		
    5.【获取全类名】
          String getName()  
    

    函数式编程

    函数式编程:

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

    匿名内部类:

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

    Lambda表达式:

    当某个方法需要一个参数,这个参数类可以是一个接口并且接口只有一个方法时可用Lambda
        1-一些参数
        2-一个箭头
        3-一段代码
        格式:(参数列表)->{一些重写方法的代码};
        可省略内容:
              1-括号中参数列表的数据类型,可省略
              2-括号中的参数如果只有一个,那么类型和括号都可以省略
              3-如果{}中代码只有一行,无论是否有返回值,都可以省略({},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)出来
                }
                //-----lambda实现
                printString(p->System.out.println(arg));
                p即print()方法的参数str,
                      System.out.println(arg)即相当于该方法的方法体
                //-----引用实现
                printString(System.out::println);
    
    【定义类对象引用方法】
    	//-----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);
    	}
    	//-----Lambda表达式实现
    	int numberabs = method(-10, (n)->{
    		return Math.abs(n);
    	});
    	//-----引用实现
    	int numberabs2 = method(-10, Math::abs);
    	
    【super引用父类方法】
    	super::父类方法名
    	
    【this引用本类方法】
    	this::本类方法名
    	
    【类引用构造方法】
    	//定义一个方法,参数传w递姓名和PsesonBuilder接口,方法中通过姓名创建Person对象
    	public static void printName(String name,PersonBuilder pb) {
    		Person person = pb.builPerson(name);
    		System.out.println(person);
    	}
    	//-----lambda表达式实现
    	//调用printName,传递Lambda表达式
    	printName("迪丽热巴", (String name)->{
    		return new Person(name);
    	});
    	//-----引用实现
    	//创建对象已知,new
    	printName("古力娜扎", Person::new);//使用Person类的带参构造方法,通过传递的姓名创建对象
    
    	例子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) 其实就是在内存中生成了一个该注解接口的子类实现对象
    • 调用注解对象中定义的抽象方法(即注解的属性)获取属性值

  • 相关阅读:
    C/C++笔试题
    #include "" 和 #include <> 的区别
    cc、gcc、g++、CC的区别概括
    在shell脚本中调用另一个脚本的三种不同方法(fork, exec, source)
    vi复制粘贴
    cleartool常用命令
    [转]Tomcat日志详解
    Profile
    Bean的初始化和销毁
    SpringEL和资源调用
  • 原文地址:https://www.cnblogs.com/xiaoaiying/p/13341327.html
Copyright © 2020-2023  润新知