阶段一:java基础篇05

目录

一、java注解

二、java反射机制

三、java1.8新特性

 

一、Java注解(jdk1.5+)

1、注解概述

注解:Annotation

编写代码时可以在不改变代码原逻辑的情况下,在源文件中通过注解的方式嵌入补充信息,并且注解的信息可以在类的编译、加载、运行时被读取,执行有关操作

在JavaSE中,注解的使用目的简单,主要有用来标记方法的重写@Override,标记过时的方法,测试方法等;在JavaEE开发中,注解扮演者特别重要的角色,通常与反射一同使用。

框架 = 注解 + 反射 + 设计模式

 

2、注解的使用

  • 注解通常在方法或属性上方标识,有的注解后的()中可以添加相关元素,取决于注解是如何定义的
  • 注解在编译时及逆行格式的检查,JDK内置的几个基本注解使用方法:
    • @Override : 限定重写父类方法,该注解只能用于方法
    • @Deprecated: 用于表示所修饰的元素(类、方法)已经过时。(旧结构存在缺陷或已经有其它更好的选择)
    • @SuppressWarnings : 抑制编译器警告
  • 在后面的使用中,多用来代替配置文件,实现容器注入功能。

 

3、元注解

jdk为我们提供了四种元注解,他们分别是:

  • @Retention : 指定所修饰的Annotion的生命周期
  • 参数RetentionPolicy.XXX
    • SOURCE: 只在源码保留,编译时将它忽视 
    • CLASS:只保留到编译时候
    • RUNTION: (默认),保留到运行时,可被JVM加载到内存中
  • @Target: 指定所修饰的Annotion可以被那些结构所使用
  • 参数:ElementType.XXX
    • TYPE:    给类加注解
    • FIELD:   给属性加注解
    •  METHOD:   给方法加注解
    • PARAMETER:   给方法内参数加注解
    • CONSTRUCTOR:  给构造器加注解
    • LOCAL_VARIABLE:   给局部变量加注解
    • ANNOTATION_TYPE:    给注解添加注解
    • PACKAGE:   给包添加注解 
  • @Inherited: 被它修饰的Annotion将具有继承性
  • @Repeatable: 被修饰的Annotion被javadoc解析后可以保留下来​​​​​​​

 

4、自定义注解

步骤:

  1. 注解声明为@interface
  2. 内部定义成员,用value表示
  3. 可以指定成员默认值,用default定义
  4. 如果自定义注解内没有成员,表明该注解代表一个标识
  5. 自定义注解还需要搭配元注解使用
@Inherited
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public @interface MyAnnotion1 {
    int value() default 12;
    
}

 

5、如何获得注解信息

前提:此注解的元注解Retention中声明的生命周期为RUNTIME

然后通过反射来获取到相关的信息,那我们来看看是如何通过反射获取到注解信息!

JDK1.8中新增:可重复注解、类型注解

 

二、java反射机制

 

1、反射概述

  • Reflection反射机制允许程序在执行期借助于Reflection API取得任何类的内部信息,并能直接操作任意对象的内部属性及方法
    • ​​​​​​​Reflection API:
      • java.long.Class
      • java.long.reflect.Method
      • java.long.reflect.Field
      • java.long.reflect.Constructor...
  • 反射机制是被视为动态语言的关键,在运行时才能确定到底运行的是什么。
  • 反射机制依靠JVM的加载器将类加载到内存中,然后获取相关类的信息
    • 在运行时​​​​​​​可以判断对象所属的类
    • 在运行时构造任意类的对象
    • 运行时可以判断一个类所具有的成员变量和方法
    • 在运行时获取泛型信息
    • 运行时可调用任何对象的方法
    • 运行时处理注解
    • 生成动态代理

 

2、Class类的加载过程

  1. 程序先执行javac.exe命令,生成一个或多个(.class)字节码文件。
  2. 我们使用java.exe命令对某个字节码文件进行解释运行。相当于将某个字节码文件加载到内存中。此过程就称为类的加载。
  3. 加载到内存中的类,我们就称为运行时类,此运行时类,就作为Class的一个实例。

获取Class的四种方式:

①调用运行时类的属性:类.class

Class clazz1 = Person.class;

②通过运行时类的对象,调用getClass()

 Person p1 = new Person();
        Class clazz2 = p1.getClass();

③调用Class的静态方法:forName(String classPath)

Class clazz3 = Class.forName("com.xiongmdd.Person");

④使用类的加载器:ClassLoader 

 ClassLoader classLoader = ReflectText.class.getClassLoader();
Class clazz = classLoader.loadClass("com.xingmdd.Person");

Class实例可以是:class,interface,数组,enum,annotation,基本数据类型,void

 

3、反射的应用

①创建运行时类的对象

  • newInstance():创建运行时类的对象
  • 前提:必须访问到运行时类的空参构造器
Class<Person> clazz = Person.class;

Person llj= clazz.newInstance();
System.out.println(llj);

②获取运行时类的完整结构

  • 我们可以通过反射,获取对应的运行时类中所有的属性、方法、构造器、父类、接口、父类的泛型、包、注解、异常
    • getFields():  获取当前运行时类及其父类中声明为public访问权限的属性
    • getDeclaredFields():  获取当前运行时类中声明的所属性。(不包含父类中声明的属性)
    • getMethods():  获取当前运行时类及其所父类中声明为public权限的方法
    • getDeclaredMethods():  获取当前运行时类中声明的所方法。(不包含父类中声明的方法)
    • getConstructors():  获取当前运行时类中声明为public的构造器
    • getDeclaredConstructors():  获取当前运行时类中声明的所的构造器
    • getSuperclass():获取当前运行时类的父类
    • getGenericSuperclass():获取运行时类的带泛型的父类
    • getInterfaces():获取运行时类实现的接口
    • getPackage(): 获取运行时类所在的包
    • getAnnotations() : 获取运行时类声明的注解

③获取运行时类的指定结构

  • 在参数中添加相关形参,即可获取指定参数的数据,但是要保证当前方法可访问: setAccessible(true)
    • getDeclaredField(String fieldName):获取运行时类中指定变量名的属性
    • getDeclaredMethod(methodName, 该方法的形参列表) :获取指定的某个方法 + 调用invoke(方法调用者,方法形参)执行方法:
    • getDeclaredConstructor(参数列表类型.class): 获取指定的构造器 +  newInstance("Xxx")创建对象;

 

三、java1.8新特性

 

1、Lambda表达式

  • Lambda表达式格式
    • -> :  lambda 操作符
    • -> :  左边:接口抽象方法形参列表
    • -> :  右边:lambda实体,重写方法的方法体
  • 例子1:

 Runnable r1 = () -> System.out.println("重写的run方法方法体内");

    r2.run(); 

  •  例子2:  

 Comparator<Integer> c1 = (o1,o2) -> Integer.compare(o1,o2);  //只有一条语句时,return {} 可省略

int com = com2.compare(32,21);

语法格式:

1、无参无返回值 :                                                             ()-> {  代码; };

2、需要一个参数,无返回值:                             (String str)-> { 代码; };

3、数据类型可有编译器判断得出:                                (str) -> { 代码; };

4、若只有一个型参,()可以以省略 :                               str -> { 代码;};

5、参数多且有返回值:                                                 (x,y) -> { 代码;return 代码; };

6、只有一条返回语句:return 和 {} 都可以省略 :       (x,y) -> 返回代码;

 

2、函数式接口

  • 果一个接口中,只声明了一个抽象方法,则此接口就称为函数式接口。
  • 我们可以在一个接口上使用 @FunctionalInterface 注解,这样做可以检查它是否是一个函数式接口。
    > Lambda表达式的本质:作为函数式接口的实例
  • Java8中关于Lambda表达式提供的4个基本的函数式接口:

 

3、方法引用

方法引用就是Lambda表达式,也就是函数式接口的一个实例,通过方法的名字来指向一个方法。

格式:类(或对象) :: 方法名

  1. 对象 :: 实例方法
  2. 类 :: 静态方法
  3. 类 :: 实例方法  (难度)
public void test1() {

	Consumer<String> con1 = str -> System.out.println(str);
	con1.accept("西安");
        //

	PrintStream ps = System.out;
	Consumer<String> con2 = ps::println;
	con2.accept("xi'an");
}

public void test2() {
	Comparator<Integer> com1 = (t1,t2) -> Integer.compare(t1,t2);
	System.out.println(com1.compare(12,21));

        //
	Comparator<Integer> com2 = Integer::compare;
	System.out.println(com2.compare(12,3));

}

public void test3() {
	Comparator<String> com1 = (s1,s2) -> s1.compareTo(s2);
	System.out.println(com1.compare("abc","abd"));

	//

	Comparator<String> com2 = String :: compareTo;
	System.out.println(com2.compare("abd","abm"));
}

 

4、构造器引用与数组引用

  • 类名::new
       Supplier<Employee>  sup1 = () -> new Employee();
       System.out.println(sup1.get());

       System.out.println("*******************");

       Supplier<Employee>  sup2 = Employee :: new;
       System.out.println(sup2.get());

 

  • 数组类型[ ] :: new
public void test4(){
    Function<Integer,String[]> func1 = length -> new String[length];
    String[] arr1 = func1.apply(5);
    System.out.println(Arrays.toString(arr1));

    System.out.println("*******************");

    Function<Integer,String[]> func2 = String[] :: new;
    String[] arr2 = func2.apply(10);
    System.out.println(Arrays.toString(arr2));

}

 

jdk1.8还有很多新增的特性,以后再做更详细的分享哦

 

下一阶段:mySQL数据库!

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值