java基础知识③:反射和注解以及Java 8的新特性

目录

一、反射和注解

1、反射

2、注解

二、Java 8的新特性

1、Lambda 表达式:

2、Stream API:

3、函数式接口:

4、方法引用:

5、接口的默认方法和静态方法:

6、新的时间日期API(Date/Time API):

7、CompletableFuture:

8、Optional类:

9、并行数组:


具体详细说明如下:

一、反射和注解

反射和注解是Java中的两个重要特性,它们可以为开发人员提供更高的灵活性和扩展性。下面详细讲解一下Java中的反射和注解。

1、反射

  1. 反射是什么 反射是Java提供的一种机制是指程序在运行时能够检测和修改自身行为的能力,用于在运行时检查、调用和实例化类、方法、属性等。通过反射,开发人员可以在运行时动态地获取类的信息,并在运行时操作类的方法、构造函数、属性等。

  2. 反射的优缺点 反射的优点在于它可以在运行时动态地获取和操作类的信息。可以实现一些动态的功能,例如在运行时创建类的实例、调用方法、获取属性等。反射的缺点在于它会导致性能下降和安全性问题。使用反射会导致代码运行速度变慢,因为在运行时需要进行额外的检查和调用。而且,反射可以绕过一些访问控制限制,可能引发安全隐患。

  3. 反射的应用场景 反射的应用场景非常广泛,例如:

  • 编写通用框架和工具:通过反射可以实现通用的操作,例如动态加载类、调用方法、获取属性等。
  • ORM框架:ORM框架可以根据对象的注解信息来生成相应的SQL语句或者根据查询结果动态生成对象。
  • 单元测试:通过反射可以实现对私有方法和属性的访问,方便编写单元测试代码。

反射的相关类和方法——Java中关于反射的主要类和方法有:

  • Class类:表示一个类或者接口。可以通过Class类获取类的信息,例如类的构造函数、方法、属性等。
  • Constructor类:表示一个类的构造函数。通过Constructor类可以创建一个类的实例。
  • Method类:表示一个类的方法。通过Method类可以调用一个类的方法。
  • Field类:表示一个类的属性。通过Field类可以访问和修改一个类的属性。

反射的基本用法——下面是通过反射获取和操作类的信息的基本用法:

Class 类: Java 中的每个类都有一个与之对应的 Class 对象,这个 Class 对象包含了该类的结构信息,通过这个对象,可以获取类的构造方法、字段、方法等信息。

  • 获取类的Class对象:可以使用以下三种方式获取一个类的Class对象。
    • 使用类的.class语法:Class clazz = MyClass.class;
    • 使用对象的getClass()方法:Class clazz = myObject.getClass();
    • 使用 Class.forName() 方法

获取类的构造方法、字段、方法:通过 Class 对象可以获取类的构造方法、字段和方法,进而进行实例化对象、访问和调用相关成员。

动态创建对象:可以使用反射来动态地创建对象实例,而不需要在编译时就确定对象类型。动态调用方法:使用反射可以在运行时动态地调用对象的方法。

  • 获取类的构造函数:
    • 获取所有的公共构造函数:Constructor[] constructors = clazz.getConstructors();
    • 获取指定参数类型的构造函数:Constructor constructor = clazz.getConstructor(String.class, int.class);
  • 创建类的实例:Object instance = constructor.newInstance("example", 123);
  • 调用类的方法:
    • 获取所有的公共方法:Method[] methods = clazz.getMethods();
    • 调用指定方法:Object result = method.invoke(instance, arg1, arg2);
  • 获取类的属性:
    • 获取所有的公共属性:Field[] fields = clazz.getFields();
    • 获取指定属性:Field field = clazz.getField("fieldName");
    • 访问属性:Object value = field.get(instance);
    • 修改属性:field.set(instance, value);

以下是一个简单的 Java 反射示例,演示了如何使用反射来获取类的信息以及动态创建对象和调用方法:

import java.lang.reflect.Constructor;
import java.lang.reflect.Method;public class ReflectionExample {public static void main(String[] args) throws Exception {// 获取 Class 对象Class<?> clazz = Class.forName("com.example.MyClass");// 获取构造方法并创建对象Constructor<?> constructor = clazz.getConstructor();Object obj = constructor.newInstance();// 获取方法并调用Method method = clazz.getMethod("myMethod", String.class);method.invoke(obj, "Hello, Reflection!");}
}

2、注解

  1. 注解是什么 注解是一种用于在代码中添加元数据信息的形式化规范。它可以用于描述类、方法、属性等的特性和行为,以及用于生成代码、配置框架等。注解是一种被动元素,不会直接影响代码的运行,但可以被编译器、工具和框架读取和利用。

  2. 注解的优点 注解的优点在于它可以使代码更加简洁、可读性更高,并且可以提供更高的配置和扩展性。使用注解可以将一些重复的代码抽取为注解,提高了代码的可读性和可维护性。另外,注解可以用于配置框架,提供了更高的灵活性和扩展性。

  3. 注解的应用场景 注解的应用场景非常广泛,例如:

  • 标记注解:用于给代码添加标记,用于编写通用的框架和工具。
  • 配置注解:用于配置框架、工具等的行为和特性。
  • 测试注解:用于编写单元测试、集成测试等。
  • ORM框架:用于描述对象和关系之间的映射关系。
  • 文档生成:用于生成文档的注解,例如Javadoc。

元注解——元注解是用于注解其他注解的注解。Java提供了一些元注解,可以用于定义新的注解。常见的元注解有:

  • @Retention:指定注解的保留策略,有三种取值:RetentionPolicy.SOURCE、RetentionPolicy.CLASS、RetentionPolicy.RUNTIME。
  • @Target:指定注解可以应用的目标元素,例如类、方法、属性等。
  • @Documented:指定注解可以被包含在Javadoc中生成文档。
  • @Inherited:指定注解可以被子类继承。

注解的相关注解 Java中关于注解的相关注解有:

  • @Override:用于标记方法覆盖父类方法。
  • @Deprecated:用于标记过时的方法或者类。
  • @SuppressWarnings:用于抑制编译器警告。
  • @FunctionalInterface:用于标记函数式接口。

自定义注解 Java允许开发人员定义自己的注解。自定义注解需要使用@interface关键字来定义,注解可以包含成员变量和方法。例子如下:

// 定义一个注解
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface MyAnnotation {String value() default "";
}// 使用注解
public class MyClass {@MyAnnotation("example")public void myMethod() {// do something}
}

注解的解析 在Java中,可以通过反射对注解进行解析和处理。可以使用以下方法来解析注解:

  • 获取注解信息:可以使用以下两种方式获取一个元素上的某个注解信息。
    • 使用元素的getAnnotation(Class annotationClass)方法:MyAnnotation annotation = element.getAnnotation(MyAnnotation.class);
    • 使用元素的getAnnotationsByType(Class annotationClass)方法:MyAnnotation[] annotations = element.getAnnotationsByType(MyAnnotation.class);
  • 获取注解属性的值:可以使用注解的属性方法来获取注解属性的值,例如annotation.value()。

总结:反射和注解是Java中的两个重要特性,它们可以为开发人员提供更高的灵活性和扩展性。通过反射,开发人员可以在运行时动态地获取类的信息,并在运行时操作类的方法、构造函数、属性等。注解是一种用于在代码中添加元数据信息的形式化规范,它可以用于描述类、方法、属性等的特性和行为,以及用于生成代码、配置框架等。掌握反射和注解的知识,可以帮助我们编写更灵活、可扩展的代码,并提高开发效率。

二、Java 8的新特性

Java 8引入了许多新特性,以下是其中一些重要的新特性:

1、Lambda 表达式:

  • Lambda表达式是Java 8最引人注目的特性之一,它使得在Java中可以更加方便地实现函数式编程。Lambda表达式提供了一种简洁的语法来表示匿名函数语法,从而使得代码更加简洁和易读。

举个简单例子,可以使用Lambda表达式来实现一个简单的排序方法:

List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Collections.sort(names, (String a, String b) -> a.compareTo(b));

 使用Lambda表达式作为sort方法的参数,这使得排序的逻辑更加清晰和简洁。

2、Stream API:

引入了 Stream API,它提供了一种更加便捷的方式来对集合数据进行操作和处理。通过Stream API,我们可以进行流式的操作,比如过滤、映射、聚合等,从而可以更加方便地进行数据处理。例如,可以使用Stream API来统计一个列表中包含多少个偶数:

List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9);
long count = numbers.stream().filter(n -> n % 2 == 0).count();
System.out.println("偶数个数:" + count);

使用了stream方法将列表转换为Stream,并且通过filter方法过滤出偶数,然后使用count方法统计偶数的个数。

3、函数式接口:

Java 8 引入了函数式接口的概念,即只包含一个抽象方法的接口。函数式接口可以与 Lambda 表达式结合使用。通过 @FunctionalInterface 注解可以明确地标识出函数式接口,使得编译器能够及早地发现不符合函数式接口定义的错误。

比如,可以定义一个简单的函数式接口来表示一个操作:

@FunctionalInterface
interface Operation {int operate(int a, int b);
}

然后可以使用Lambda表达式来实现这个函数式接口:

Operation add = (a, b) -> a + b;
System.out.println(add.operate(3, 5)); // 输出: 8

函数式接口的引入使得 Java 中的函数式编程更加方便和直观。

4、方法引用:

方法引用允许直接通过方法的名称引用已经存在的方法。

5、接口的默认方法和静态方法:

默认方法:接口中可以包含默认方法,即为接口提供一个默认的实现。这使得在给接口添加新方法时,不会破坏已经存在的实现类。例如,定义一个接口Shape,并在接口中添加一个默认方法来计算面积:

interface Shape {double area();default void printArea() {System.out.println("Area: " + area());}
}

这样,所有实现Shape接口的类都会自动继承printArea方法,避免了需要修改所有实现类的情况。 

6、新的时间日期API(Date/Time API):

Java 8引入了全新的时间日期API,该API提供了更加灵活和易用的日期时间处理方式,同时修复了旧的Date和Calendar类的很多问题。比如,可以使用新的时间日期API来计算两个日期之间的天数差:

LocalDate startDate = LocalDate.of(2022, 1, 1);
LocalDate endDate = LocalDate.of(2022, 12, 31);
long days = ChronoUnit.DAYS.between(startDate, endDate);
System.out.println("相差天数:" + days);

通过这个例子,可以看到新的时间日期API提供了更加直观和方便的方式来处理日期时间相关的操作。 

7、CompletableFuture:

CompletableFuture 是用于异步编程的一个重要类,在 Java 8 中引入。它提供了一种方便的方式来处理异步操作,并且可以轻松地组合多个异步任务。它提供了更加灵活的 Future 接口。举个例子,我们可以使用 CompletableFuture 来进行异步执行并获取结果:

CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "Hello").thenApply(s -> s + " world").thenApply(String::toUpperCase);
System.out.println(future.get()); // 输出: HELLO WORLD

在这个例子中,首先使用 supplyAsync 方法异步执行一个任务,然后通过 thenApply 方法进行任务链式操作,最终获取到了结果。

8、Optional类:

Java 8引入了Optional类,它提供了一种更加优雅和安全的方式来处理可能为空的值,避免了空指针异常。通过Optional类,我们可以避免使用null,并且在代码中更加明确地表达出某个值可能为空的情况。

举个例子,可以使用Optional类来避免空指针异常:

Optional<String> name = Optional.ofNullable(getName());
System.out.println("名字:" + name.orElse("未知"));

在上面的例子中,如果getName()返回的是空值,那么orElse方法将会提供一个默认值来代替空值。

9、并行数组:

在 Java 8 中,新增了一些便捷的方法来对数组进行并行操作。比如,我们可以使用 parallelPrefix 方法来实现并行计算数组的前缀和

int[] array = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
Arrays.parallelPrefix(array, (x, y) -> x + y);
System.out.println(Arrays.toString(array)); // 输出: [1, 3, 6, 10, 15, 21, 28, 36, 45, 55]

上面的例子中,使用 parallelPrefix 方法对数组进行了并行操作,计算出了每个位置的前缀和。

以上就是Java 8的一些重要新特性,每一个特性都带来了巨大的改变和提升,可以使得Java代码更加简洁、高效和易读。Java 8 的这些新特性使得 Java 语言在功能上更加丰富和便捷,为开发人员提供了更多的选择和解决方案。通过灵活运用这些特性,可以使得 Java 代码更加高效和易维护。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/222297.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

文心一言4.0使用指南

文心一言4.0使用指南 在线体验&#xff1a;体验地址 一、文心一言能力如何 不管百度公司如何&#xff0c;就AI大模型来说&#xff0c;文心一言和其他国内产品相比&#xff0c;还是具有相当大的优势的&#xff0c;可以说是在个人的使用方面&#xff0c;我认为是最顶级的。 但…

Unity中的ShaderToy

文章目录 前言一、ShaderToy网站二、ShaderToy基本框架1、我们可以在ShaderToy网站中&#xff0c;这样看用到的GLSL文档2、void mainImage 是我们的程序入口&#xff0c;类似于片断着色器3、fragColor作为输出变量&#xff0c;为屏幕每一像素的颜色&#xff0c;alpha一般赋值为…

微信小程序单图上传和多图上传

图片上传主要用到 1、wx.chooseImage(Object object) 从本地相册选择图片或使用相机拍照。 参数 Object object 属性类型默认值必填说明countnumber9否最多可以选择的图片张数sizeTypeArray.<string>[original, compressed]否所选的图片的尺寸sourceTypeArray.<s…

从开源项目中学习如何自定义 Spring Boot Starter 小组件

前言 今天参考的开源组件Graceful Response——Spring Boot接口优雅响应处理器。 具体用法可以参考github以及官方文档。 基本使用 引入Graceful Response组件 项目中直接引入如下maven依赖&#xff0c;即可使用其相关功能。 <dependency><groupId>com.feiniaoji…

Leetcode 2454. 下一个更大元素 IV

Leetcode 2454. 下一个更大元素 IV题目 给你一个下标从 0 开始的非负整数数组 nums 。对于 nums 中每一个整数&#xff0c;你必须找到对应元素的 第二大 整数。如果 nums[j] 满足以下条件&#xff0c;那么我们称它为 nums[i] 的 第二大 整数&#xff1a; j >nums[j] > nu…

螺旋矩阵算法(leetcode第59题)

题目描述&#xff1a; 给你一个正整数 n &#xff0c;生成一个包含 1 到 n2 所有元素&#xff0c;且元素按顺时针顺序螺旋排列的 n x n 正方形矩阵 matrix 。示例 1&#xff1a;输入&#xff1a;n 3 输出&#xff1a;[[1,2,3],[8,9,4],[7,6,5]] 示例 2&#xff1a;输入&#…

电商API代码如何接入写

要接入一个API&#xff0c;通常需要遵循以下步骤&#xff1a; 1. 【了解API文档】&#xff1a;首先&#xff0c;需要了解你想要接入的API的文档。这些文档通常会包含关于如何使用该API的重要信息&#xff0c;比如基本的请求格式、可用的端点&#xff08;endpoints&#xff09;…

SQL Server ,使用递归查询具有层级关系的数据。

假设我们有一个表格 Employees&#xff0c;其中包含员工的层级关系信息&#xff0c;每一行包括员工的ID、姓名以及上级员工的ID。 下面是一个示例表格及其数据&#xff1a; Employees ---------------------- EmployeeID | Name | ManagerID ---------------------- 1 …

6-46.矩阵运算

根据main函数中矩阵对象的定义与使用&#xff0c;定义相关的矩阵类Array&#xff0c;并利用运算符重载的方法实现矩阵的加法与输入输出操作。&#xff08;为简化问题&#xff0c;矩阵中元素为2位以内整数&#xff0c;要求矩阵按照行列的格式输出&#xff0c;每个元素占3位宽度&…

Process On在线绘制流程图

目录 一.ProcessOn 1.1.介绍 1.2.直接网上使用 二.绘制门诊流程图 三.绘制住院流程图 四.绘制药库采购入库流程图 五.绘制OA会议流程图 今天就到这里了哦!!!希望能帮到你哦&#xff01;&#xff01;&#xff01; 一.ProcessOn 1.1.介绍 ProcessOn&#xff08;流程&#…

MFC 加载本地文件设置图标

基于单文件/多文件版 1、在CMainFrame中设置 int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct) {//...........// 从本地文件加载图标HICON hIcon (HICON)::LoadImage(NULL, L"./vip.ico", IMAGE_ICON, 0, 0, LR_LOADFROMFILE);if (hIcon){ // 设置窗口图…

Linux,Web网站服务(一)

1.准备工作 为了避免发生端口冲突&#xff0c;程序冲突等现象&#xff0c;建议卸载使用RPM方式安装的httpd [rootnode01 ~]# rpm -e http --nodeps 挂载光盘到/mnt目录 [rootnode01 ~]# mount /dev/cdrom /mnt Apache的配置及运行需要apr.pcre等软件包的支持&#xff0c;因此…

牛客网SQL训练2—SQL基础进阶

文章目录 一、基本查询二、数据过滤三&#xff1a;函数四&#xff1a;分组聚合五&#xff1a;子查询六&#xff1a;多表连接七&#xff1a;组合查询八&#xff1a;技能专项-case when使用九&#xff1a;多表连接-窗口函数十&#xff1a;技能专项-having子句十一&#xff1a;技能…

Web信息收集,互联网上的裸奔者

Web信息收集&#xff0c;互联网上的裸奔者 1.资产信息收集2.域名信息收集3.子域名收集4.单点初步信息收集网站指纹识别服务器类型(Linux/Windows)网站容器(Apache/Nginx/Tomcat/IIS)脚本类型(PHP/JSP/ASP/ASPX)数据库类型(MySQL/Oracle/Accees/SqlServer) 5.单点深入信息收集截…

Linux-----10、查找命令

# 查找命令 # 1、 命令查找 Linux下一切皆文件&#xff01; which 命令 &#xff1a;找出命令的绝对路径 whereis 命令 &#xff1a;找出命令的路径以及文档手册信息 [rootheima ~]# which mkdir /usr/bin/mkdir[rootheima ~]# whereis mkdir mkdir: /usr/bin/mkdir /usr/…

Py-While循环语句

while循环语句&#xff1a; 注意&#xff1a; while的条件需要得到布尔类型的结果&#xff0c;true继续循环&#xff0c;false退出循环需要设置循环终止的条件&#xff0c;不可以让程序一直无线循环运行下去空格缩进与if一样 语法格式:(只要条件满足会一直循环) while 布尔…

一款计算机顶会爬取解析系统 paper info

一款计算机顶会爬取解析系统 paper info 背景项目实现的功能 技术方案架构设计项目使用的技术选型 使用方法本地项目部署使用ChatGPT等大模型创建一个ChatGPT助手使用阿里云 顶会数据量 百度网盘pfd文件json文件 Q&A github链接 &#xff1a;https://github.com/codebricki…

Java面试题13

1.数据库的三范式是什么&#xff1f; 数据库的三范式是指数据库设计的一种规范&#xff0c;用来规定如何将数据进行组织和存储&#xff0c;以便减 少冗余、提高数据的一致性和准确性。具体来说&#xff0c;三范式分为三个层次&#xff1a; 第一范式&#xff08;1NF&#xff09…

(反序列化)小记录

目录 [CISCN 2023 华北]ez_date 绕过MD5和sha1强相关绕过 date()绕过 payload [FSCTF 2023]ez_php [CISCN 2023 华北]ez_date <?php error_reporting(0); highlight_file(__FILE__); class date{public $a;public $b;public $file;public function __wakeup(){if(is_a…

【快刊】Springer旗下2区,仅1个月左右录用,国人极其友好!

计算机类 • 好刊解读 今天小编带来Springer旗下计算机领域好刊&#xff0c;如您有投稿需求&#xff0c;可作为重点关注&#xff01;后文有相关领域真实发表案例&#xff0c;供您投稿参考~ 01 期刊简介 ✅出版社&#xff1a;Springer ✅影响因子&#xff1a;4.0-5.0 ✅期刊…