当我们将一个对象放入集合中,集合不会记住此对象的类型,
当再次从集合中取出此对象时,改对象的编译类型变成了Object类型,但其运行时类型任然为其本身类型
取出集合元素时需要人为的强制类型转化到具体的目标类型,强转的时候容易报错"java.lang.ClassCastException"
使集合能够记住集合内元素各类型,且能够达到只要编译时不出现问题,运行时就不会出现“java.lang.ClassCastException”异常呢
一般Java中,使用变量E表示集合元素类型。K表示关键字,V表示值。T(或者U、S)表示"任意类型"。
1.集合中用到泛型
Map hm = new HashMap();
List list = new ArrayList();
2.类中用到泛型
2.1成员变量可以使用泛型
/**
* @description: ${description}
* @create: 2019-02-16
* 泛型类
* 用在成员变量上,只能使用引用类型
**/
public class Lottery {
private T number;
public Lottery(T number) {
this.number = number;
}
public T getNumber() {
return number;
}
public void setNumber(T number) {
this.number = number;
}
public static void main(String[] args) {
Lottery lottery1=new Lottery("123abc");
Lottery lottery2=new Lottery(123);
System.out.println(lottery1.getNumber());
lottery2.setNumber(456);
System.out.println(lottery2.getNumber());
}
}
package fanxing;
/**
* @description: ${description}
* @create: 2019-02-17
**/
public class Iphone{
void method1(K k){
System.out.println(k.toString());
}
V method2(V v){
return v;
}
K method3(String s){
System.out.println(s.length());
return (K) (s+s);
}
public static void main(String[] args) {
Iphone iphone6=new Iphone<>();
iphone6.method1("kakaka");
Integer integer = iphone6.method2(9999);
System.out.println(integer);
String s = iphone6.method3("6666");
System.out.println(s);
}
}
public interface Fruit {
public T get();
}
3.2接口的实现类1
public class PriceFruit implements Fruit {
@Override
public Integer get() {
return 666;
}
}
3.3接口的实现类2
public class RedFruit implements Fruit {
@Override
public String get() {
return "red apple";
}
}
4泛型方法
普通方法、构造方法和静态方法中都可以使用泛型
package fanxing;
/**
* @description: ${description}
* @create: 2019-02-17
**/
public class Swap {
static void swap(T[] a,int i,int j){
T temp=a[i];
a[i] = a[j];
a[j]=temp;
}
public static void main(String[] args) {
Swap s=new Swap();
String[] a1={"a","b","c","d"};
s.swap(a1,1,2);
for (String string:a1
) {
System.out.print(string+" ,");
}
System.out.println();
Integer[] a2={1,2,3,4,5,6};
s.swap(a2,1,2);
for (Integer i:a2
) {
System.out.print(i);
}
}
}
1,泛型通配符
使用"?“通配符可以引用其他各种参数化的类型,”?"通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
例:Collection>可以适配Collection、Collection或Collection等
2,限定通配符的上边界
用于匹配Number及Number的子类
extends Number>
3,限定通配符的下边界
//用于匹配Integer及Integer的父类。
super Integer>
4,Java 中的泛型基本上是在编译器中实现。编译器进行执行类型检查和类型推断,然后生成普通的非泛型的字节码。编译器使用泛型类型信息保证类型安全,然后在生成字节码之前将其清除。这种实现技术称为擦除(erasure)
5,泛型实际是提供给Javac编译器使用的。限定输入类型,让编译器挡住源程序中的非法输入,编译器编译带类型说明的集合时会去除掉"类型"信息。程序运行期间,没有任何泛型泛型的痕迹。使程序运行效率不受影响,对于参数化的泛型类型,getClass()方法的返回值和原始类型完全一样
6,成功编译过后的class文件中是不包含任何泛型信息的。泛型信息不会进入到运行时阶段
7,Java中没有所谓的泛型数组一说