JDK5特性分析

文章目录

  • 泛型应用
    • 概述
    • 应用类型
    • 泛型通配符
    • 泛型类型擦除
    • 小节面试分析
  • 注解应用
    • 概述
    • 注解定义
    • 注解与反射
    • 小节面试分析
  • 拆箱封箱
    • 概述
    • 自动封箱
    • 自动拆箱
    • 小节面试分析
  • 枚举类型
    • 概述
    • 枚举定义
    • 枚举类型应用
    • 小节面试分析
  • 可变参数
    • 概述
    • 应用实践
    • 小节面试分析
  • 总结(Summary)
    • 重难点分析
    • FAQ分析
    • Bug分析

泛型应用

概述

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

应用类型

泛型接口

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

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);
}

泛型类

泛型抽象类,代码如下:

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);
	}
}

泛型方法

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

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) {

}
}

泛型通配符

无界通配符

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

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

有界通配符

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

 指定泛型下限:<? 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>();

泛型类型擦除

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

小节面试分析

  • 为什么要使用泛型?
  • 泛型有哪些应用方式?
  • 如何理解泛型类型擦除?
  • 泛型应用时有哪些通配符?

注解应用

概述

注解是JDK1.5推出的一种新的应用类型(特殊的class),是一种元数据(Meta Data):用于描述接口,类,属性,方法,参数等。可以将其理解为一个为生活中的标签.

注解定义

我们先来看一下,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;
}

注解与反射

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

@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);

小节面试分析

  • Java中的注解如何定义?
  • Java中注解的作用是什么?
  • Java中的注解与Annotation接口是什么关系?
  • 如何获取类及成员上状态为运行时有效的注解对象?

拆箱封箱

概述

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

自动封箱

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

Integer n1=100;

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

自动拆箱

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

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

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

小节面试分析

  • 如何理解Java中的自动拆箱和封箱特性?
  • Java中的自动拆箱和封箱能给给编码带来哪些便利?

枚举类型

概述

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

枚举定义

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

public enum RetentionPolicy {
    SOURCE,
    CLASS,
    RUNTIME
}

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

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

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

枚举类型应用

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

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);

小节面试分析

  • Java中的枚举是什么?
  • Java中的枚举应用在什么场景?
  • Java中的枚举类型如何定义?
  • Java中的枚举实例是什么时候构建的?
  • Java中的枚举类中的可以定义构造方法吗?

可变参数

概述

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

应用实践

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

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 array
      for (int i = 0; i < names.length; ++i) {
         System.out.print(" " + names[i]);
      }
      System.out.println();
   }
}

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

小节面试分析

  • 可变参数一般应用在什么场景?
  • 一个方法内部可以多个可变参数吗?
  • 一个方法内部有多个参数时,可变参数可以是第一个参数吗?

总结(Summary)

重难点分析

  • 泛型定义及应用。
  • 注解的定义及应用。
  • 自动拆箱封箱应用。
  • 枚举的定义及应用。
  • 可变参数的应用。

FAQ分析

  • 泛型有哪些应用类型?
  • 泛型通配符你知道多少?
  • 如何理解注解,如何定义?
  • 注解反射是如何结合使用的?
  • 可变参数为我们的应用带来哪些便利?

Bug分析

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

青木编码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值