Java8 Lambda表达式模板方法实现解析

Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容。在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解。

Java1.5引入了注解,当前许多java框架中大量使用注解,如Hibernate、Jersey、Spring。注解作为程序的元数据嵌入到程序当中。注解可以被一些解析工具或者是编译工具进行解析。我们也可以声明注解在编译过程或执行时产生作用。

在使用注解之前,程序源数据只是通过java注释和javadoc,但是注解提供的功能要远远超过这些。注解不仅包含了元数据,它还可以作用于程序运行过程中、注解解释器可以通过注解决定程序的执行顺序。例如,在Jersey webservice 我们为方法添加URI字符串的形式的PATH注解,那么在程序运行过程中jerser解释程序将决定该方法去调用所给的URI。

创建Java自定义注解

创建自定义注解和创建一个接口相似,但是注解的interface关键字需要以@符号开头。我们可以为注解声明方法。我们先来看看注解的例子,然后我们将讨论他的一些特性。

package com.journaldev.annotations;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Inherited;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Documented
@Target(ElementType.METHOD)
@Inherited
@Retention(RetentionPolicy.RUNTIME)
  public @interface MethodInfo{
  String author() default 'Pankaj';
  String date();
  int revision() default 1;
  String comments();
}
  • 注解方法不能带有参数;
  • 注解方法返回值类型限定为:基本类型、String、Enums、Annotation或者是这些类型的数组;
  • 注解方法可以有默认值;
  • 注解本身能够包含元注解,元注解被用来注解其它注解。

这里有四种类型的元注解:

  • @Documented —— 指明拥有这个注解的元素可以被javadoc此类的工具文档化。这种类型应该用于注解那些影响客户使用带注释的元素声明的类型。如果一种声明使用Documented进行注解,这种类型的注解被作为被标注的程序成员的公共API。
  • @Target——指明该类型的注解可以注解的程序元素的范围。该元注解的取值可以为TYPE,METHOD,CONSTRUCTOR,FIELD等。如果Target元注解没有出现,那么定义的注解可以应用于程序的任何元素。
  • @Inherited——指明该注解类型被自动继承。如果用户在当前类中查询这个元注解类型并且当前类的声明中不包含这个元注解类型,那么也将自动查询当前类的父类是否存在Inherited元注解,这个动作将被重复执行知道这个标注类型被找到,或者是查询到顶层的父类。
  • @Retention——指明了该Annotation被保留的时间长短。RetentionPolicy取值为SOURCE,CLASS,RUNTIME。

Java内建注解

Java提供了三种内建注解。

  • @Override——当我们想要复写父类中的方法时,我们需要使用该注解去告知编译器我们想要复写这个方法。这样一来当父类中的方法移除或者发生更改时编译器将提示错误信息。
  • @Deprecated——当我们希望编译器知道某一方法不建议使用时,我们应该使用这个注解。Java在javadoc 中推荐使用该注解,我们应该提供为什么该方法不推荐使用以及替代的方法。
  • @SuppressWarnings——这个仅仅是告诉编译器忽略特定的警告信息,例如在泛型中使用原生数据类型。它的保留策略是SOURCE(译者注:在源文件中有效)并且被编译器丢弃。

我们来看一个java内建注解的例子参照上边提到的自定义注解。

package com.journaldev.annotations;

import java.io.FileNotFoundException;
import java.util.ArrayList;
import java.util.List;

public class AnnotationExample {

public static void main(String[] args) {
}

@Override
@MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 1)
public String toString() {
  return 'Overriden toString method';
}

@Deprecated
@MethodInfo(comments = 'deprecated method', date = 'Nov 17 2012')
public static void oldMethod() {
  System.out.println('old method, don't use it.');
}

@SuppressWarnings({ 'unchecked', 'deprecation' })
@MethodInfo(author = 'Pankaj', comments = 'Main method', date = 'Nov 17 2012', revision = 10)
public static void genericsTest() throws FileNotFoundException {
  List l = new ArrayList();
  l.add('abc');
  oldMethod();
}

}

相信这个例子可以不言自明并能展示在不同场景下的应用。

Java注解解析

我们将使用反射技术来解析java类的注解。那么注解的RetentionPolicy应该设置为RUNTIME否则java类的注解信息在执行过程中将不可用那么我们也不能从中得到任何和注解有关的数据。

package com.journaldev.annotations;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;

public class AnnotationParsing {

public static void main(String[] args) {
  try {
  for (Method method : AnnotationParsing.class
    .getClassLoader()
    .loadClass(('com.journaldev.annotations.AnnotationExample'))
    .getMethods()) {
    // checks if MethodInfo annotation is present for the method
    if (method.isAnnotationPresent(com.journaldev.annotations.MethodInfo.class)) {
      try {
    // iterates all the annotations available in the method
        for (Annotation anno : method.getDeclaredAnnotations()) {
          System.out.println('Annotation in Method ''+ method + '' : ' + anno);
          }
        MethodInfo methodAnno = method.getAnnotation(MethodInfo.class);
        if (methodAnno.revision() == 1) {
          System.out.println('Method with revision no 1 = '+ method);
          }

      } catch (Throwable ex) {
          ex.printStackTrace();
          }
    }
  }
  } catch (SecurityException | ClassNotFoundException e) {
      e.printStackTrace();
     }
  }

}

运行上面程序将输出:

Annotation in Method 'public java.lang.String com.journaldev.annotations.AnnotationExample.toString()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=Main method, date=Nov 17 2012)
Method with revision no 1 = public java.lang.String com.journaldev.annotations.AnnotationExample.toString()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @java.lang.Deprecated()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.oldMethod()' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=1, comments=deprecated method, date=Nov 17 2012)
Method with revision no 1 = public static void com.journaldev.annotations.AnnotationExample.oldMethod()
Annotation in Method 'public static void com.journaldev.annotations.AnnotationExample.genericsTest() throws java.io.FileNotFoundException' : @com.journaldev.annotations.MethodInfo(author=Pankaj, revision=10, comments=Main method, date=Nov 17 2012)

这就是该教程的全部内容,希望你可以从中学到些东西。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

(0)

相关推荐

  • Java8中Lambda表达式使用和Stream API详解

    前言 Java8 的新特性:Lambda表达式.强大的 Stream API.全新时间日期 API.ConcurrentHashMap.MetaSpace.总得来说,Java8 的新特性使 Java 的运行速度更快.代码更少.便于并行.最大化减少空指针异常. 0x00. 前置数据 private List<People> peoples = null; @BeforeEach void before () { peoples = new ArrayList<>(); peoples

  • 使用Java 8 Lambda表达式将实体映射到DTO的操作

    当我们需要将DTO转换为实体(Hibernate实体等)并向后转换时,我们都会面临混乱的开销代码. 在我的示例中,我将用Java 8演示代码如何变得越来越短. 让我们创建目标DTO: public class ActiveUserListDTO { public ActiveUserListDTO() { } public ActiveUserListDTO(UserEntity userEntity) { this.username = userEntity.getUsername(); ..

  • java lambda表达式用法总结

    这篇文章主要介绍了java lamda表达式用法总结,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 1.什么是函数式编程(百度百科上的解释) 2.为什么要使用函数式编程(有什么好处) 1.代码简洁,减少代码量 2.接近自然语言,容易理解 传统实现分组 List<Student> students; Map<String,List<Student>> maps = Maps.newHashMap(); for(Stude

  • Java Lambda表达式原理及多线程实现

    1.使用Lambda表达式实现多线程 public static void main(String[] args) { //使用匿名内部类的方式,实现多线程 new Thread(new Runnable() { @Override public void run() { System.out.println(Thread.currentThread().getName() + "新线程创建了!"); } }).start(); //使用Lambda表达式,实现多线程 new Thre

  • 详解Java8中的Lambda表达式

    Lambda是什么 Lambda表达式,也可称为闭包,是java8的新特性,作用是取代大部分内部类,优化java代码结构,让代码变得更加简洁紧凑. Lambda的基本语法 (expression)->expression 或 (expression)->{statements;} Lambda最重要特点 用()->{}代码块替代匿名内部类 //(param)->expression;//(param)->statment;//(param)->{statments};/

  • lambda表达式解决java后台分组排序过程解析

    需求:按照起始日期查询出数据库里一段连续日期的住院信息. 问题:数据库里的住院信息可能不是完整的,也就是在给出的日期区间里只有若干天的数据,缺少某些日期的数据. 解决: 1.需要我们先按日期分组查出数据库里有的数据: 2.然后遍历日期,将不存在的日期以日期为key,value为null插入集合里: 3.对集合里的key即日期进行排序. 注:这里分组和排序都用JDK8的新特性lambda表达式 /** * * @param startTime 开始时间 * @param endTime 结束时间

  • Java Lambda表达式与匿名内部类的联系和区别实例分析

    本文实例讲述了Java Lambda表达式与匿名内部类的联系和区别.分享给大家供大家参考,具体如下: 一 点睛 Lambda表达式与匿名内部类存在如下相同点: Lambda表达式与匿名内部类一样,都可以直接访问"effectively final"的局部变量,以及外部类的成员变量(包括实例变量和类变量). Lambda表达式创建的对象与匿名内部类生成的对象一样, 都可以直接调用从接口继承得到的默认方法. Lambda表达式与匿名内部类主要存在如下区别: 匿名内部类可以为任意接口创建实例

  • 详细分析Java Lambda表达式

    在了解Lambda表达式之前我们先来区分一下面向对象的思想和函数式编程思想的区别 面向对象的思想: 做一件事情,找一个能解决这个事情的对象,调用他的方法来解决 函数时编程思想: 只要能获取到结果,谁去做的都不重要,重视的是结果,不重视过程 使用Lambda表达式的目的是为了简化我们的代码 匿名内部类虽然也简化了我们的代码,但是Lambda比他更简单,而且语法也更加少 下面我用一段代码来演示一下二者的区别 public class Main { public static void main(St

  • Java8 lambda表达式2种常用方法代码解析

    与python不一样,python lambda是定义匿名函数,而在java8中lambda是匿名内部类 例1.用lambda表达式实现Runnable 我开始使用Java 8时,首先做的就是使用lambda表达式替换匿名类,而实现Runnable接口是匿名类的最好示例.看一下Java 8之前的runnable实现方法,需要4行代码,而使用lambda表达式只需要一行代码.我们在这里做了什么呢?那就是用() -> {}代码块替代了整个匿名类. // Java 8之前: new Thread(ne

  • Java8 Lambda表达式模板方法实现解析

    Java注解提供了关于代码的一些信息,但并不直接作用于它所注解的代码内容.在这个教程当中,我们将学习Java的注解,如何定制注解,注解的使用以及如何通过反射解析注解. Java1.5引入了注解,当前许多java框架中大量使用注解,如Hibernate.Jersey.Spring.注解作为程序的元数据嵌入到程序当中.注解可以被一些解析工具或者是编译工具进行解析.我们也可以声明注解在编译过程或执行时产生作用. 在使用注解之前,程序源数据只是通过java注释和javadoc,但是注解提供的功能要远远超

  • Java 8 动态类型语言Lambda表达式实现原理解析

    Java 8支持动态语言,看到了很酷的Lambda表达式,对一直以静态类型语言自居的Java,让人看到了Java虚拟机可以支持动态语言的目标. import java.util.function.Consumer; public class Lambda { public static void main(String[] args) { Consumer<String> c = s -> System.out.println(s); c.accept("hello lambd

  • JAVA8 lambda表达式权威教程

    Java 8新特性----Stream流 jdk8是Java 语言开发的一个主要版本,它支持函数式编程,新的 JavaScript 引擎,新的日期 API,新的Stream API 等等.今天就重点介绍一个非常重要得特性之一 lambda表达式 一:什么是 Stream? Stream(流)是一个来自数据源的元素队列并支持聚合操作 Java中的Stream并不会存储元素,而是按需计算. 数据源 流的来源. 可以是集合,数组,I/O channel, 产生器generator 等. 聚合操作 类似

  • Java Lambda 表达式源码解析

    Java Lambda 源码分析 问题: Lambda 表达式是什么?JVM 内部究竟是如何实现 Lambda 表达式的?为什么要这样实现? 一.基本概念 1.Lambda 表达式 下面的例子中,() -> System.out.println("1") 就是一个 Lambda 表达式.Java 8 中每一个 Lambda 表达式必须有一个函数式接口与之对应.Lambda 表达式就是函数式接口的一个实现. @Test public void test0() { Runnable

  • Java 8 引入lambda表达式的原因解析

    在Java8出现之前,如果你想传递一段代码到另一个方法里是很不方便的.你几乎不可能将代码块到处传递,因为Java是一个面向对象的语言,因此你要构建一个属于某个类的对象,由它的某个方法来放置你想传递的代码块. 下面看两个非常典型的例子,构造线程与比较器: 构造线程: 我们要想在另一个线程中执行一些代码逻辑时,通常会将代码放在一个实现Runnable接口的run方法当中,如下图: public static void main(String[] args) { myThread t = new my

  • Java8 lambda表达式的10个实例讲解

    目录 例1.用lambda表达式实现Runnable 例2.使用Java 8 lambda表达式进行事件处理 例3.使用lambda表达式对列表进行迭代 例4.使用lambda表达式和函数式接口Predicate 例5.如何在lambda表达式中加入Predicate 例6.Java 8中使用lambda表达式的Map和Reduce示例 例7.通过过滤创建一个String列表 例8.对列表的每个元素应用函数 例9.复制不同的值,创建一个子列表 例10.计算集合元素的最大值.最小值.总和以及平均值

  • Java8 Lambda表达式详解及实例

    第一个Lambda表达式 在Lambda出现之前,如果我们需要写一个多线程可能需要下面这种方式: Runnable runnable = new Runnable() { @Override public void run() { System.out.println("Hello runnable"); } }; ... thread.start(); 上面的例子如果改成使用Lambda就会简单许多: Runnable noArgs = ()->System.out.print

  • Java8新特性Lambda表达式的一些复杂用法总结

    简介 lambda表达式是JAVA8中提供的一种新的特性,它支持Java也能进行简单的"函数式编程". 它是一个匿名函数,Lambda表达式基于数学中的λ演算得名,直接对应于其中的lambda抽象(lambda abstraction),是一个匿名函数,即没有函数名的函数. 本文将介绍关于Java8 Lambda表达式的一些复杂用法,分享出来供大家参考学习,下面来一起看看详细的介绍: 复杂用法实例 传入数组ids,在list<Obj>上操作,找出Obj中id想匹配的,并且按

  • java8 forEach结合Lambda表达式遍历 List操作

    我就废话不多说了,大家还是直接看代码吧~ @Test void testJava8ForeachMap() { Map<String, Integer> items = new HashMap<>(); items.put("A", 10); items.put("B", 20); items.put("C", 30); items.put("D", 40); items.put("E&quo

随机推荐