泛型
1、具有一个或多个泛型变量的类型被称之为泛型类
class A<T>{}
2、在创建泛型类实例时,需要为其类型变量赋值
A<String> a = new A<String>();
如果创建实例时,不给类型变量赋值,那么会有一个警告。
3、泛型方法:具有一个或多个类型变量的方法,称之为泛型方法
class A<T>{
public T fun(T t1){
}
}
fun()方法不是泛型方法,是泛型类中的一个方法
public <T>T fun (T t1){} -->是泛型方法
泛型方法和泛型类没什么关系,泛型方法不一定非要在泛型类中。
4、泛型在类中或方法中的使用
泛型类中使用泛型
成员类型
返回值和参数类型
局部变量的引用上
class A<T>{
private T bean;//泛型可在成员变量上使用
public T fun(T t){}//泛型可以在类中的方法上(返回值和参数类型)使用
public void fun2(){//泛型还可以在局部变量的引用类型上使用
T b=...
new T();//不行
}
}
5、泛型的继承和实现
class A<T>{}
class AA extends A<String>{}//不是泛型类,只是他爸爸是泛型类
5.1、继承泛型类
子类不是泛型类:需要给父类传递类型常量
当给父类传递的类型常量为String时,那么在父类中所有T都会被String替换
子类是泛型类,可以给父类传递类型常量,也可以传递类型变量
class AA1 extends A<Integer>{}
class AA3<E> extends A<E>{}
泛型的通配符
1、通配符使用的场景
方法的形参
2、通配符的优点
使方法更加通用
3、通配符分类
无界通配:?
子类限定:? extend Object
父类限定: ? super Integer
4、通配符缺点
使变量使用上不再方便
无界:参数和返回值为泛型的方法,不能使用
子类:参数为泛型的方法不能使用
父类:返回值为泛型的方法不能使用
5、比较通配符
boolean addAll(Collection<E> c)
List<Number> numList = new ArrayList<Number>();
List<Integer> intList = new ArrayList<Integer>();
numList.addAll(intList);//addAll(Collection<Number> c),传递的是List<Integer>
boolean addAll(Collection<? extends E> c)
List<Number> numList = new ArrayList<Number>();
List<Integer> intList = new ArrayList<Integer>();
numList.addAll(intList);//addAll(Collection<? extends Number> c),传递的是List<Integer>
注解【配置文件 需要有人读 否则无意义,往往是框架读比如tomcat】
1、什么是注解
语法:@注释名称
注解的作用:替代xml配置文件
servlet3.0中,就可以不再使用web.xml,而是所有配置都使用注解
注解是由框架来读取使用
2、注解
定义注解类:框架的工作
使用注释:我们的工作
读取注释(反射):框架的工作
3、定义注解类
class A{}
interface A{}
enum A{}
@interface A{} 所有的注解都是Annotation的子类
4、使用注解
可以把注解作用在:类、方法、属性、构造器、方法参数、局部变量也可以把注解作用在包上[没啥用]
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnn{}
下面的代码会出错
@MyAnn
package xx;
public class A{}
因为java不让这么注解包,如果想给包添加注解必须再创建一个文件:package-info.java文件,然后在这个方法中给出对包的注解
package-info.java
@MyAnn package xx
反射包上的注解
Package p = Package.getPackage("my.xx");
MyAnn myAnn = p.getAnnocation(MyAnn.class);
注解的作用目标
类
方法
构造器
参数
局部变量
包
5、注解的属性
定义属性
格式:类型 属性名();
@interface MyAnno1{
int age();
String name();
}
使用注解时给属性赋值
@MyAnno1(age=10,name="zhangSan")
注解属性的默认值:在定义注解时,可以给注解定义默认值
int age() default 100;
在使用注解时,可以不给带有默认值的属性赋值
名为value的属性的特权
当使用注解时,如果只(仅一个的时候)给名为value的属性赋值时,可以省略"value=",
例如@MyAnno1(value="hello")可以书写成@MyAnno1("hello")
注解属性的类型
8中基本类型
String
Enum
Class
注解类型
以上类型的一维数组类型 包装类不行比如Integer
当给数组类型的属性赋值时,若数组元素的个数为1时,可以省略大括号
@MyAnno1(
a=100,
b="hello",
c=MyEnum1.A,
d=String.class,
e=@MyAnno2(aa=1,bb="2"),
f={"a","b"},
h=100
)
public class Demo3 {
}
@interface MyAnno1{
int a();
String b();
MyEnum1 c();
Class d();
MyAnno2 e();
String[] f();
int[] h();
}
@interface MyAnno2{
int aa();
String bb();
}
//枚举要求是其中的一个
enum MyEnum1{
A,B,C
}
6、注解的作用目标限定以及保定策略限定
6.1让一个注解,它的作用目标只能在类上,不能在方法上,这就叫作用目标的限定
在调用注解时,给注解添加注解,这个注解是@Target
枚举就几个选项
@Target(value={ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
@interface MyAnno1{
}
6.2保留策略
源代码文件(source):注解只在源代码中存在,当编译时就被忽略了
字节码文件(class):注解在源代码中存在,然后编译时会把注解信息放到了class文件,但JVM在加载类时,会忽略注解
JVM中(runtime):注解在源代码、字节码文件中存在,并且在JVM加载类时,会把注解加载到JVM内中(唯一可反射的注解)
6.3、限定注解的保留策略
使用
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnno1{
}
7、读取注解(反射)
反射泛型信息
Class-->Type getGenericSupperclss()
Type-->ParameterizedType:把Type强转成ParameterizedType类型
ParameterizedType-->参数化类型=A<String>
ParameterizedType:Type[] getActuallTypeArguments(),A<String>中的String
Type[]就是Class[],就得到了类型参数
abstract class A<T>{
public A(){
/*
* 获取子类传递的泛型信息,得到一个class
*/
// Class clazz = this.getClass();//得到子类的类型
// Type type = clazz.getGenericSuperclass();//获取传递给父类的参数化类型
// ParameterizedType pType = (ParameterizedType) type;//就是A<String>
// Type[] types = pType.getActualTypeArguments();//就是一个Class数组
// Class c = (Class) types[0];//就是String
// Class c = null;
// System.out.println(c.getName());//String或Integer
Class c= (Class) ((ParameterizedType) this.getClass().getGenericSuperclass())
.getActualTypeArguments()[0];
System.out.println(c.getName());
}
}
反射注解
1、要求
注解的保留策略必须是RUNTIME
2、反射注解需要从作用目标上返回
类上的注解,需要使用Class获取
方法上的注解,需要Method来获取
构造器的注解,需要Constructor来获取
成员上的,需要Field来获取
Class:
Method、Constructor、Field:AccessibleObject
都有一个方法:
Annotation getAnnotation(Class):返回目标上指定类型的注解
Annotation[] getAnnotations:返回目标上所有注解