探索JDK5的新特性:革新编程体验的里程碑

引言

        Java Development Kit (JDK) 5,于2004年发布,是Java发展历程中具有里程碑意义的一个版本。它不仅引入了一系列关键的编程新特性,还大大提升了开发者的生产力和代码质量。本文将带领大家深入了解JDK 5带来的变革性创新,包括泛型、枚举、for-each循环、变长参数、注解(Annotations)等核心特性。

JDK5特性分析

1. 泛型应用

1.1 概述

泛型是JDK1.5以后推出的一种编译时类型,运行时无效,我们通常可以将其理解为一种参数化类型,可以应用在接口,类,方法,属性上,用于约束类中属性,方法参数以及返回值类型,基于这种方式可以对编程过程中的接口、类、方法进行通用化设计,同时在编译阶段解决在运行时执行一些校验操作,提高其运行效率。

1.2 应用类型

1.2.1 泛型接口

单泛型参数,关键代码如下:

package com.cy.java.generic;interface Container<T>{//泛型接口void add(T t);T get(int i);int size();
}

多泛型参数,关键代码如下:

interface Task<Param,Result>{//思考map中的泛型Map<K,V>
/*** 此方法用于执行任务* @param arg 其类型由泛型参数Param决定* @return 其类型由泛型参数result决定*/
Result execute(Param arg1);
}

 

1.2.2 泛型类

泛型抽象类,代码如下:

abstract class AbsContainer<T> implements Container<T>{//泛型类
protected int size;
public int size() {
return size;
}
}

泛型具体类,代码如下:

class ArrayContainer extends AbsContainer<Integer>{
private Object[] array;
public ArrayContainer() {
this.array=new Object[16];
}
@Override
public void add(Integer t) {}@Override
Public Integer get(int i) {
return null;
}
}
class IntegerConvertTask implements Task<String,Integer>{
@Override
public Integer execute(String arg) {
return Integer.parseInt(arg);
}
}

1.2.3 泛型方法

泛型方法主要应用与类中的静态方法,但不限于静态方法,例如:

class ObjectFactory{//泛型方法public static <T>T newInstance(Class<T> cls)throws Exception{return cls.newInstance();}
}
class ContainerUtils{
public static <T>void sort(List<T> list) {}
}

1.3 泛型通配符

1.3.1 无界通配符

泛型中的无界通配符使用”?”表示,泛指一种不确定性类型。例如,可以代表一种任意参数类型(实参类型),通常会应用于变量的定义,例如:


Class<Object> c1=Object.class;//字节码对象//当编译阶段无法确定泛型类型时,应用”?”进行替换。
Class<?> c2=Class.forName("java.lang.Object");

 

1.3.2 有界通配符

泛型在应用时有时需要指定对象的上限和下限,我们称这种形式叫限定通配符,语法如下:

  • 指定泛型下限:<? super T> 表示参数是类型T或T的父类,不影响往里存,但往外取只能放在Object 对象里。

  • 指定泛型上限:<? extends T>表示参数类型是T或T的子类,上界只能外围取,不能往里放。因为编译阶段不能确定你要放入的类型。

有界通配符应用案例,构建一打印工具类,关键代码如下:

class PrintUtil{static void doPrint(List<? extends CharSequence> list){//上限
System.out.println(list.get(0));
}static void doPrint(Set<? super Integer> set){//下限
set.add(100);System.out.println(set);}}

说明,如果要从集合中读取类型T的数据, 并且不能写入,可以使用 上界通配符(<?extends>)—Producer Extends。如果要从集合中写入类型T 的数据, 并且不需要读取,可以使用下界通配符(<? super>)—Consumer Super。如果既要存又要取, 那么就要使用非限定通配符。

通配符应用分析,请问如下写法是否正确?假如不正确该如何修改?

List<Object> list1=new ArrayList<String>();
List<String> list2=new ArrayList<Object>();

1.4 泛型类型擦除

泛型是在编译阶段由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。这种实现技术称为擦除(erasure),所以说泛型是编译时的一种类型,在运行时无效,运行时候都会变成Object类型。例如,尝试基于反射技术向List<String> list=new ArrayList<String>()对象中添加整数100。

关键代码如下:

List<String> list=new ArrayList<>();
list.add("A");
list.add("B");
//list.add(100);
//在运行时将100写入到list集合//1.获取list对象的字节码对象
Class<?> cls=list.getClass();
//2.获取list字节码对象中的add方法对象
Method method=cls.getDeclaredMethod("add",Object.class);
//3.通过反射执行方法对象将100写入集合。
//执行list对象的method方法
method.invoke(list, 100);
System.out.println(list);

1.5 小节面试分析

  • 什么是泛型?(编译时的一种参数化的类型)

  • 为什么要使用泛型?(通用编程,提高运行效率)

  • 泛型有哪些应用方式?(类泛型,接口泛型,方法泛型)

  • 如何理解泛型类型擦除?(泛型在运行时无效,默认所有类型为Object类型)

  • 泛型应用时有哪些通配符?(无界,上届限定通配符,下届限定通配符)

2. 注解应用

2.1 概述

注解是JDK1.5推出的一种新的应用类型(特殊的class),是一种元数据(Meta Data):用于描述接口,类,属性,方法,参数等。可以将其理解为一个为生活中的标签(例如买了件衣服,衣服上贴了个牌子)。Java中所有的注解都默认继承Annotation接口。

2.2 注解定义

我们先来看一下,Java中自带的Overide注解,代码如下:

@Target(value=METHOD)
@Retention(value=SOURCE)
public @interface Override{}

在实际项目注解可能由第三方定义,也可能会由我们自己定义,例如

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)//表示只能描述类
@interface Entity{}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)//表示只能描述属性
@interface ID{}

其中:@Target 用于描述定义的注解能够修饰的对象,@Retention 用于描述定义的注解何时有效。

创建注解时,指定注解属性,例如:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
@interface Component{
/**注解中的属性定义*/
String value() default "";
boolean lazy() default true;
}

2.3 注解与反射

使用注解描述类及成员,代码如下:

@Entity
class Book{
@ID
private Integer id;
}
@Component(value="lruCache",lazy=false)
class HashLruCache{}

通过反射技术判定注解的存在,例如:

//1.判定类上是否有Entity注解
Class<?> c1=Book.class;
boolean flag = c1.isAnnotationPresent(Entity.class);
System.out.println(flag);
//2.判定对象中id属性上是否有ID注解
//2.1获取属性id
Field f1 = c1.getDeclaredField("id");
//2.2判定属性上是否有ID注解
flag=f1.isAnnotationPresent(ID.class);
System.out.println(flag);

通过反射获取注解属性值,例如:

//如何获取类或属性等上面注解呢?
//1.获取字节码对象(入口)
Class<?> cls=HashLruCache.class;
//2.获取类上的注解
Component c=
cls.getDeclaredAnnotation(Component.class);
//3.获取注解中属性的值
String value=c.value();
boolean lazy=c.lazy();
System.out.println(value);
System.out.println(lazy);

2.4 小节面试分析

  • Java中的注解如何定义?(@interface)

  • Java中注解的作用是什么?(描述类、属性、方法、参数用于赋予这些成员特定含义)

  • Java中的注解与Annotation接口是什么关系?(is a的关系,继承关系)

  • 如何获取类及成员上状态为运行时有效的注解对象?(反射技术)

3. 拆箱封箱

3.1 概述

Java中不仅提供了8种基本数据类型,还为了更好的体现面向对象特性,专门提供了8种基本数据类型对应的对象封装类型。Jdk1.5之后为了更好的实现基本数据类型和8种封装类型之间的转换,提供自动封箱和拆箱机制。

3.2 自动封箱

自动拆箱就是将基本类型自动转换为对象数据类型,例如:

Integer n1=100;

其中,对于等号右边的值会自动调用Integer.valueOf方法转换为对象类型。

3.3 自动拆箱

自动拆箱就是对象类型自动转换为基本数据类型,例如:

Integer n1=Integer.valueOf(100);
int n2=n1;//自动拆箱

说明,无论是自动拆箱,还是自动封装,为Java编程过程中的类型转换提供了很好便利。

3.4 小节面试分析

  • 如何理解Java中的自动拆箱和封箱特性?

  • Java中的自动拆箱和封箱能给编码带来哪些便利?

4. 枚举类型

4.1 概述

枚举是JDK1.5以后推出的一种新的类型(特殊的类),主要用于更加严格的约束变量类型,例如现有一个产品对象,此对象有一个性别属性,请问此属性的类型如何定义呢,还有现在有一订单,我们如何定义订单状态呢?在实际项目中这些类型的定义我们通常会借助枚举进行实现。

4.2 枚举定义

Java中的枚举借助enum关键字进行定义,例如JDK中的枚举:

public enum RetentionPolicy {SOURCE,CLASS,RUNTIME
}

枚举类型,通常应用于值固定的实例类型,例如一周七天,代码如下:

enum Week {MONDAY, TUESDAY, WEDNESDAY,THURSDAY, FRIDAY, SATURDAY, SUNDAY
}

其中:Week中MONDAY, TUESDAY等都属于枚举的实例,这些实例都是在类加载时创建,可通过枚举类名直接访问,例如Week.MONDAY。

4.3 枚举类型应用

定义一性别枚举类,例如:

enum Gender{//Gender.class
MALE,FEMALE,NONE; 
}

在定义产品类型时,应用性别枚举类,例如:

class Product{
/**性别要求*/
private Gender gender=Gender.NONE;
public void setGender(Gender gender) {
this.gender = gender;
}
}

定义含有带参构建函数的枚举类型,例如:

enum Sex{
//枚举类型的对象是在类加载时创建
MALE("男"),FEMALE("女");//执行带参构造函数
private String name;
private Sex(String name){
this.name=name;
}
public String getName() {
return name;
}
}

定义会员类,应用Sex枚举类型,例如:

class Member{
private Sex sex=Sex.MALE;
public void setSex(Sex sex) {
this.sex = sex;
}
}

枚举应用测试,案例如下:

Member m=new Member();
String sexStr="MALE";
//将字符串转换为枚举类型时,字符串的值需要
//与枚举类中的实例名相同(区分大小写)
//Sex sex=Sex.valueOf(sexStr);
Sex sex=Enum.valueOf(Sex.class, sexStr);
System.out.println(sex.getName());
m.setSex(sex);

4.4 小节面试分析

  • Java中的枚举是什么?

  • Java中的枚举应用在什么场景?

  • Java中的枚举类型如何定义?

  • Java中的枚举实例是什么时候构建的?

  • Java中的枚举类中的可以定义构造方法吗?

5. 可变参数

5.1 概述

JDK5中允许方法最后一个参数使用带三个点的类型进行定义,在进行方法调用时可传入任意个数的实际参数,其目标主要是用于简化方法名相同,参数类型也相同,但参数个数不同的一系列方法的定义。

5.2 应用实践

可变参数应用案例,关键代码如下:

public class JDK5TryVarargs {public static void main(String[] args) {greets("Hello", "Peter", "Paul");}public static void greets(String greeting, String... names) {System.out.print(greeting + ",");// varargs received as an arrayfor (int i = 0; i < names.length; ++i) {System.out.print(" " + names[i]);}System.out.println();}
}

说明,可变参数只能应用在方法参数列表中的最后一个参数的定义上。

5.3 小节面试分析

  • 可变参数一般应用在什么场景?

  • 一个方法内部可以多个可变参数吗?

  • 一个方法内部有多个参数时,可变参数可以是第一个参数吗?

6. 总结(Summary)

6.1 重难点分析

  • 泛型定义及应用。

  • 注解的定义及应用。

  • 自动拆箱封箱应用。

  • 枚举的定义及应用。

  • 可变参数的应用。

6.2 FAQ分析

  • 泛型有哪些应用类型?

  • 泛型通配符你知道多少?

  • 如何理解注解,如何定义?

  • 注解反射是如何结合使用的?

  • 可变参数为我们的应用带来哪些便利?

6.3 Bug分析

  • NullPointerException

本篇文章主要对应JAVA基础常见核心面试点中的JDK5新特性。有兴趣可以查看该文章。

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

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

相关文章

自定义异常处理演示

​ 为了防止黑客从前台异常信息&#xff0c;对系统进行攻击。同时&#xff0c;为了提高用户体验&#xff0c;我们都会都抛出的异常进行拦截处理。 一、全局异常处理 编写一个异常拦截类&#xff0c;如下&#xff1a;ControllerAdvice&#xff0c;很多初学者可能都没有听说过…

《最新出炉》系列初窥篇-Python+Playwright自动化测试-19-处理鼠标拖拽-中篇

1.简介 上一篇中&#xff0c;主要是介绍了拖拽的各种方法的理论知识以及实践&#xff0c;今天宏哥讲解和分享一下划取字段操作。例如&#xff1a;需要在一堆log字符中随机划取一段文字&#xff0c;然后右键选择摘取功能。 2.划取字段操作 划取字段操作就是在一段文字中随机选…

Linux系统——http协议介绍

目录 引言——Internet起源 一、http协议——超文本传输协议 1.http相关概念 2.访问浏览器的过程 3.http协议通信过程 4.http相关技术 4.1WEB开发语言 4.2html 4.3CSS 4.4JS 5.MIME——Multipurpose Internet Mail Extensions 多用途互联网邮件扩展 6.URI URN URL的…

ubuntu配置pip

windows的pip镜像 在C:\Users\当前用户\下创建.pip文件夹在.pip下创建pip.ini文件编辑pip.ini添加如下内容 [global] index-url https://mirror.baidu.com/pypi/simple [install] trusted-host https://mirror.baidu.com/pypi ubuntu的pip镜像 当前用户的pip镜像 1. 进入用…

申请 Segfault 的免费 VPS

打开 Segfault 的官网&#xff1a;https://shell.segfault.net/&#xff0c;然后点击“I’m new here”在弹出的窗口中&#xff0c;复制以保存访问密钥点击 continue&#xff0c;进入主页&#xff0c;然后敲回车以创建服务器如需重返回自己的服务器&#xff0c;可以在官网点击“…

【Redis,Java】Redis的两种序列化方式—nosql数据库

redis和mysql的区别&#xff1a; redis是属于nosql的数据库&#xff0c;而mysql是属于sql数据库&#xff0c;redis是属于nosql数据库。mysql是存储在磁盘中的&#xff0c;redis是存储在内存中的&#xff0c;所以redis的读取书读快。这里所说的redis代表nosql&#xff0c;而mysq…

【wails】(1):使用go做桌面应用开发,wails框架入门学习,在Linux上搭建环境,运行demo项目,并打包测试

1&#xff0c;视频地址 https://www.bilibili.com/video/BV1fK421b7QC/ 【wails】&#xff08;1&#xff09;&#xff1a;使用go做桌面应用开发&#xff0c;wails框架入门学习&#xff0c;在Linux上搭建环境&#xff0c;运行demo项目&#xff0c;并打包测试 2&#xff0c;参考…

在Ubuntu中使用python

目录 一、利用vim使用python 1、下载vim 2、使用vim创建python文件 3、编辑完成后的vim操作 4、如何运行 5、vim常见操作 二、安装Jupyter 1、更新系统 2、安装pip 注&#xff1a;pip无法应用的原因及解决方案 3、安装Jupyter 4、打开Jupyter 三、安装其他Python模…

ActiveMQ高可用架构涉及常用功能整理

ActiveMQ高可用架构涉及常用功能整理 1. activemq的集群模式2. 镜像模式高可用系统架构和相关组件2.1 架构说明2.2 相关概念说明2.3 消息模型2.3.1 点对点2.3.2 发布订阅 3. activemq常用命令4. activemq配置集群5. 疑问和思考5.1 activemq的数据删除策略是怎样的&#xff1f;5…

C++ 中的单例模式singleton

C 中的单例模式 引言 在面向对象编程中&#xff0c;设计模式是解决常见问题的最佳实践。单例模式是其中之一&#xff0c;它确保一个类只有一个实例&#xff0c;并提供一个全局访问点来获取该实例。在本文中&#xff0c;我们将详细介绍 C 中的单例模式。 什么是单例模式&…

【软考问题】-- 1 - IT知识 - 信息化发展

一、基础问题 问题1:信息系统的生命周期可以简化为哪5个阶段? (1)系统规划(可行性分析与项目开发计划)(2)系统分析(需求分析) (3)系统设计(概要设计、 详细设计) (4)系统实施(编码、 测试) (5)系统运行和维护问题2:国家信息化体系六要素分别是什么? 1信息…

ChatGPT-用ChatGPT指令,自学任何领域的系统知识

1. 指令位置 Github仓库&#xff1a;Mr Ranedeer AI Tutor 但是需要开通chatgtp plus版本&#xff0c;并且打开代码解释器 2 使用 学习内容 开始学习 GPT甚至可以给你思考题&#xff0c;给出的答案还能进行评价 配置 通过配置表修改 深度 学习风格 沟通风格 语气风格 …

探索Nginx:一款高效、稳定的Web服务器和反向代理工具

在网站性能优化和架构设计中&#xff0c;Nginx以其高性能、低资源消耗和良好的扩展性成为了许多开发者和服务器管理员的首选。本文将为您详细介绍Nginx的概念、特点、安装、配置和使用&#xff0c;帮助您更好地了解并运用这款优秀的工具。 一、Nginx简介 Nginx&#xff08;发…

基于RWKV架构推理成本大降:Eagle 7B模型的十倍效能提升

前言 在今天这个数据驱动的时代&#xff0c;大型语言模型&#xff08;LLM&#xff09;在处理自然语言处理&#xff08;NLP&#xff09;任务时的效能和效率成为了众多研究者和工程师关注的焦点。尤其是在推理成本日益攀升的背景下&#xff0c;如何在保持甚至提升模型性能的同时…

【Java】数据类型与变量

1.数据类型 在Java中数据类型主要分为两类&#xff1a;基本数据类型和引用数据类型。 基本数据类型有四类八种&#xff1a; 四类&#xff1a;整型、浮点型、字符型以及布尔型八种&#xff1a; 注意&#xff1a;不论是在16位系统还是32位系统&#xff0c;int都占用4个字节&am…

js设计模式:原型模式

作用: 使用js特有的原型链机制,可以通过Object.create方法创建新对象,将一个对象作为另外一个对象的原型 也可以通过修改原型链上的属性,影响新对象的行为 可以更方便的创建一些对象 示例: let obj {getName: function(){return this.name},getAge:function(){return this…

VINS-FUSION 在Opencv4下编译报错,且ceres也报错

Opencv报错 /home/monica/Documents/code/vins-fusion-old-ws/src/VINS-Fusion-master/camera_models/src/chessboard/Chessboard.cc:20:38: error: ‘CV_GRAY2BGR’ was not declared in this scope 20 | cv::cvtColor(image, mSketch, CV_GRAY2BGR); | …

代码随想录算法训练营29期|day55 任务以及具体安排

第九章 动态规划part12 309.最佳买卖股票时机含冷冻期 class Solution {public int maxProfit(int[] prices) {//0代表持股票&#xff0c;1代表保持卖出状态&#xff0c;2代表卖出股票。3代表冷冻int[][] dp new int[prices.length][4];dp[0][0] -prices[0];for(int i 1 ; …

axios封装终极版实现token无感刷新及全局loading

前言 关于axios全局loading的封装博主已经发过一次了&#xff0c;这次是在其基础上增加了token的无感刷新。 token无感刷新流程 首次登录的时候会获取到两个token&#xff08;AccessToken&#xff0c;RefreshToken&#xff09;持久化保存起来&#xff08;localStorage方案&a…

iOS 使用Image I/O 实现超大图片降采样

一个图片解码成未压缩的位图的时候&#xff0c;占用的内存和图片的文件大小没有关系&#xff0c;和图片的尺寸大小有关系&#xff0c;尺寸越大&#xff0c;所需要的像素点越多&#xff0c;所以超大图片&#xff0c;我们需要进行优化处理 这里直接上降采样代码 给UIImage 添加…