}
泛型具体类,代码如下:
class ArrayContainer extends AbsContainer{
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 newInstance(Class cls)
throws Exception{
return cls.newInstance();
}
}
class ContainerUtils{
public static void sort(List list) {
}
}
无界通配符
泛型中的无界通配符使用”?”表示,泛指一种不确定性类型。例如,可以代表一种任意参数类型(实参类型),通常会应用于变量的定义,例如:
Class 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 list1=new ArrayList();
List list2=new ArrayList();
泛型是在编译阶段由编译器执行类型检查和类型推断,然后生成普通的非泛型的字节码。这种实现技术称为擦除(erasure),所以说泛型是编译时的一种类型,在运行时无效,运行时候都会变成Object类型。例如,尝试基于反射技术向List list=new ArrayList()对象中添加整数100。
关键代码如下:
List 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;
}
}
枚举应用测试,案例如下: