泛型
Java中的泛型,只在编译阶段有效
泛型类
- 对象实例化时不指定泛型,默认为:Object
- 泛型不同的引用不能相互赋值
public class Test {
public static void main(String[] args) {
A<String> a = new A<>(); //在new A的对象指定泛型的类型String
a.setKey("xxxx"); //对象使用setKey(T key)方法,中的key的形参就是String
String key = a.getKey(); // T getKey(),返回值就由new对象类型确定,为String
}
}
/**
* 此处的泛型T可以任意取名,A,B,C.....,一般使用T,意为type
* @param <T>
*/
class A<T> {
private T key;
public void setKey(T key) {
this.key = key;
}
public T getKey() {
return key;
}
}
泛型接口
public class Test1 {
public static void main(String[] args) {
Sub<Object> sub1 = new Sub<>();
Sub<String> sub2 = new Sub<>();
Stb stb = new Stb();
}
}
interface IB<T> {
T test(T t);
}
/**
* 未传入泛型实参时,与泛型类的定义相同,在声明类的时候,需要将泛型的声明一起加入类中
* @param <T>
*/
class Sub<T> implements IB<T> {
@Override
public T test(T t) {
return t;
}
}
/**
* 如果实现接口时指定了具体的泛型类型,这个类实现接口所有方法都替换成指定的数据类型
*/
class Stb implements IB<String> {
@Override
public String test(String s) {
return s;
}
}
泛型方法
public class Test1 {
public static void main(String[] args) {
Cc<Object> cc = new Cc<>();
cc.test("aaaa");
//泛型方法,在调用之前没有固定的数据类型,在调用之后,传入的参数是什么类型,就把泛型改成什么类型
//也就是说,泛型方法会在调用时确定具体数据类型
Integer integer = cc.test1(12);
Boolean aBoolean = cc.test1(true);
}
}
class Cc<E> {
private E e;
public static void test3() {
//在静态方法中不能使用类定义的泛型,如果要使用泛型,只能使用静态方法自己定义的泛型
// System.out.println(e);
}
/**
* 无返回值的泛型方法
* @param s
* @param <T>
*/
public <T> void test(T s) {
//在类上定义的泛型可以在普通方法中使用
System.out.println(e);
T t = s;
}
/**
* 有返回值的泛型方法,返回值类型是泛型
* @param s
* @param <T>
* @return
*/
public <T> T test1(T s) {
return s;
}
/**
* 形参是可变参数的泛型方法
* @param ts
* @param <T>
*/
public <T> void test2(T... ts) {
for (T t : ts) {
System.out.println(t);
}
}
}
泛型通配符 ?
不确定集合中的元素的具体数据类型,用?表示所有类型
public class Test2 {
public static void main(String[] args) {
List<String> list1 = new ArrayList<>();
List<Integer> list2 = new ArrayList<>();
Dd dd = new Dd();
dd.test(list1);
dd.test(list2);
}
}
class Dd {
public void test(List<?> list) { //test方法需要一个list集合的参数,但是不确定集合中存放的具体数据类型
}
}
有限制的通配符
- <? extends Person> : (无穷小,Person]
- <? super Person> : [Person,无穷大)
- <? extends Comparable> : 只允许泛型为实现Comparable接口的实现类的引用调用
public class Test2 {
public static void main(String[] args) {
Dd dd = new Dd();
List<C1> c1List = new ArrayList<>();
dd.test1(c1List);
List<D1> d1List = new ArrayList<>();
dd.test1(d1List);
// List<B1> b1List = new ArrayList<>();
// dd.test1(b1List);
dd.test2(c1List);
// dd.test2(d1List);
List<A1> a1List = new ArrayList<>();
dd.test2(a1List);
List<IAImpl> iaList = new ArrayList<>();
dd.test3(iaList);
}
}
class Dd {
public void test1(List<? extends C1> list) { //list的元素数据类型是C1及其子类
}
public void test2(List<? super C1> list) { //list的元素数据类型是C1及其父类
}
public void test3(List<? extends IA> list) { //list的元素数据类型是IA的实现类
}
}
class A1 {}
class B1 extends A1 {}
class C1 extends B1 {}
class D1 extends C1 {}
interface IA {}
class IAImpl implements IA {}
枚举类
使用enum定义枚举类,枚举类也可以实现接口
public class Test3 {
public static void main(String[] args) {
Season spring = Season.SPRING;
spring.showInfo();
Season summer = Season.SUMMER;
summer.showInfo();
Season autumn = Season.AUTUMN;
autumn.showInfo();
Season winter = Season.WINTER;
winter.showInfo();
spring.test();
}
}
enum Season implements Itest {
SPRING("春天", "春暖花开"), //此处相当于在调用有参的私有构造Season(String name, String desc)
SUMMER("夏天", "炎炎夏日"),
AUTUMN("秋天", "秋高气爽"),
WINTER("冬天", "寒风凛冽");
private final String name;
private final String desc;
Season(String name, String desc) {
this.name = name;
this.desc = desc;
}
public void showInfo() {
System.out.println(name + ":" + desc);
}
@Override
public void test() {
System.out.println("这是实现的Itest接口的test方法");
}
}
interface Itest {
void test();
}
注解
三个基本的注解Annotation:
- @Override:限定重写父类方法,该注释只能用于方法
- @Deprecated:用于表示某个程序元素(类,方法等)已过时
- @SuppressWarnings:抑制编译器警告
public class Test4 {
public static void main(String[] args) {
new TestB().test1();
@SuppressWarnings("rawtypes")
List list = new ArrayList();
}
}
class TestA {
public void test() {
}
}
class TestB extends TestA {
@Override
public void test() {
super.test();
}
@Deprecated
public void test1() {
}
}
自定义Annotation:
使用**@interface**关键字
class TestA {
@TestAnn(id = 100, desc = "姓名")
String name;
public void test() {
}
}
@Target(ElementType.FIELD) //这个注解类是给其他类的属性做注解
@Retention(RetentionPolicy.RUNTIME) //定义注解的生命周期
@Documented //把注解提取到document文档中
@interface TestAnn {
public int id() default 0;
public String desc() default "";
}