java泛型相关内容

12

java泛型是JDK1.5中引入的新特性,本质是参数化类型,类型安全的集合,强制集合元素的类型必须一致。提高方法的重用性。

1.泛型的分类

1.1 泛型类

在类名的后面加一对尖括号,加括号中包含一个字母,这个字母是占位符,占位符使用一个大写字母表示,创建对象时替换为实际的类型,如果有多个用逗号隔开,这样的类称为泛型类。

常用占位符:E(element)、T(Type)、V(Value)、K(Key)

格式:public class GenericDemo1 {}

使用:

  • 1.创建实例变量,不能创建静态的 T n;
  • 2.作为方法的参数
  • 3.作为方法的返回值
public T print(T t) {
        return t;
  }
//在类名的后面加一对尖括号,加括号中包含一个字母,这个字母是占位符
//占位符使用一个大写字母表示,创建对象时替换为实际的类型
//如果有多个用逗号隔开<E,T>
//E(element)  T(Type)  V(Value)  K(Key)
//    这样的类称为泛型类
public class GenericDemo1<T> {
    //1.创建实例变量,不能创建静态的
    T n;

    //2.作为方法的参数
    public T print(T t) {
        //3.作为方法的返回值
        return t;
    }
}

class Test {
    public static void main(String[] args) {
        GenericDemo1<String> demo = new GenericDemo1<>();
        demo.n = "123";
        System.out.println(demo.print("asd"));
    }
}

1.2 泛型接口

在接口名的后面加一对尖括号,尖括号包含占位符,这样的接口就称为泛型接口。

格式:public interface GenericDemo2{}

使用:作为参数、返回值 T print(T t);

//在接口名的后面加一对尖括号,尖括号包含占位符,这样的接口就称为泛型接口
public interface GenericDemo2<T> {
    //1.作为参数、返回值
    T print(T t);
}

//实现接口1
class Mouse implements GenericDemo2<String> {
    @Override
    public String print(String s) {
        return s;
    }
}
//实现接口2
class Upan<E> implements GenericDemo2<E>{
    @Override
    public E print(E e) {
        return e;
    }
}
class Test2 {
    public static void main(String[] args) {
        Mouse mouse = new Mouse();
        //GenericDemo2<String> mouse2 = new Mouse()
        System.out.println(mouse.print("123"));

        Upan<String> upan = new Upan<>();
        //GenericDemo2<String> upan2 = new Mouse()
        System.out.println(upan.print("456"));
    }
}

[wppay]

1.3 泛型方法

在方法名的返回值的前面加一对尖括号,尖括号包含占位符,这样的方法就称为泛型方法。

public <T> T show(T t) {
        return t;
}

public T show(T t) 报错。

//在方法名的返回值的前面加一对尖括号,尖括号包含占位符,这样的方法就称为泛型方法
public class GenericMethodDemo3 {
    //public T show(T t) 报错
    public <T> T show(T t) {
        return t;
    }
}

class Test3 {
    public static void main(String[] args) {
        GenericMethodDemo3 demo3 = new GenericMethodDemo3();
        demo3.show("q");
        demo3.show(100);
        demo3.show(3.14);
        demo3.show(new Object());
    }
}

2.注意

在类中不能声明静态属性:

  • 泛型在创建对象的时候确定,而静态的要在类加载的时候。
  • static修饰的属性是静态属性先于对象,泛型类型取决于创建对象时传入的实际类型。

泛型不能在类中初始化对象或数组,但是可以声明引用或数组:

  • 实例化对象需要分配空间,没有确定类型不能开辟空间。
  • 初始化数组时需要给元素进行分配空间,泛型类型不确定无法分配空间。

在类中不能使用泛型声明参数个数相同的重载方法。

使用不同实际类型创建出的泛型类对象的引用不可以相互赋值。

3.泛型集合

特点:

  • 编译时可检查,而非运行时抛出异常。
  • 访问时,不必类型转换(自动拆箱)

4.问号?

  • 表示任意类型
  • public static void show(ArrayList args)
  • 对集合不能添加、修改
  • ? extends Student:只能是小于等于Student的类型:泛型上限
  • ? super Student:只能是大于等于Student的类型:泛型下限
public class ArrayListDemo4 {
    public static void main(String[] args) {
        ArrayList<String> o = new ArrayList<>();
        ArrayList<Integer> o1 = new ArrayList<>();
        o.add("q");
        o.add("w");
        o.add("e");
        o1.add(1);
        o1.add(2);
        o1.add(3);
        /*show(o);
        show(o1);*/
        ArrayList<Student> students = new ArrayList<>();
        show(students);
    }

    //泛型上限
    /*public static void show(ArrayList<? extends Student> args) {

    }*/
    //泛型下限
    public static void show(ArrayList<? super Student> args) {

    }
}

class Student {

}

5.面试题

TreeSet treeSet = new TreeSet<>();为什么后面<>?

java泛型是JDK1.5加入的新特性,可以在编译时期对类型进行检查,避免程序运行时出错,在运行过程中泛型会被擦除。至于<>,是因为可以根据环境上下文推断出类型,故可以省去。

[/wppay]