标签:常用 print 包装类 创建 数组 return ext cas hash
1.泛型的由来:
原因:在泛型出现之前,针对不同的数据类型时可以通过方法的重载和向上转型的方式指定;
1) 方法的重载:
缺点:代码繁杂,复用性差
public class Demo {
private int a;
private float b;
public void set(int a) {
this.a = a;
}
public void set(float b) {
this.b = b;
}
}
2) 自动转型:
缺点:向下转型编译时检验不到错误,需要手动类型检查(instanceof);
public static void main(String[] args) {
Object num=1; //int-->Integer-->Object
int num1=(int)num; //jdk1.7以前可以从Object类型转为Integer类型,不能直接强制转转为int类型;
String str=(String)num;//编译时检验不到错误,需要手动类型检查(instanceof)
System.out.println(str);//运行时抛出java.Lang.ClassCastException异常
}
为了解决以上缺点,以C++为模板参照,在jdk1.5中添加了<>泛型的概念。
2.泛型的优点:
1) 安全:编译时检查类型安全
2) 省心:所有的强制转换是隐式的自动的提高了代码的复用率
3.泛型的常用类型:
1)可以在类中使用,例如:
public class ArrayList<E> extends AbstractList<E> public class HashMap<K,V> extends AbstractMap<K,V>
2)在接口中使用,例如:
public interface Collection<E> extends Iterable<E>
3)在方法的返回类型中使用,例如:
class Demo1<T>{
T age;
public T getAge() {
return age;
}
}
4)在方法中使用,例如:
Class Demo{
//静态方法中使用,静态方法优先于对象存在,所有需加<T>
public static <T> void test(T t){
System.out.println(t);
}
public static void main(String[] args) {
Demo.test(“a”);//输出a
}
}
4.通配符
通配符的特征:
1)可以用于声明类型和声明方法的参数上,实例化时需指定,不可以用于声明类的参数上;
2)?只能输入和输出,不能修改;
3)? extends 泛型上限 <=的关系;
4)? super 泛型下限 >=的关系;
5.泛型的嵌套:从外到内一层一层拆分
6.泛型注意点
1)泛型的类型只能是引用类型,不能是基本类型,但是引用参数可以是基本类型的参数,因为会自动封装成相应的包装类
2)泛型的指定在使用时需指定泛型类型
3)泛型字母不能使用在静态属性和静态方法以及常量上,例如 static T,,final T age等
4)泛型子类可以继承泛型父类也可以继承非泛型父类,泛型父类中没有指定的泛型,子类需保留,但无需保证顺序,例如(在接口中类似,JDK1.8中, 接口中静态方法或者被default修饰的非静态方法可以定义有方法体,不需要重写,除此之外为被public static final修饰的常量属性和public abstract修饰的抽象方法):
public class Demo1 {
public static void main(String[] args) {
Integer t=3;
Demo3<Integer,Integer, Integer> demo3 = new Demo3<Integer, Integer, Integer>();
demo3.test1(t);
}
}
abstract class Demo2<T1, T2> {
T1 age;// 父类的属性随父类而定
void test1(T1 t) {
}
}
// 没有指定的类型,名称可以更改,无需顺序一致, 泛型父类中没有指定的泛型子类需保留
class Demo3<T1, T3, T2> extends Demo2<T3, String> {
T1 age;
@Override
void test1(T3 t) {// 重写的类型随父类而定,不能写为void test1(T1 t)
System.out.println(1);
}
// 当类型参数为基本类型时,可以对父类方法进行重载
void test1(int t) {
System.out.println(2);
}
}
5)泛型的拭除,父类拭除子类可以拭除,或者子类和父类同时拭除,不能父类拭除而子类不拭除,拭除的泛型类型默认为Object类型,例如(在接口中类似):
public class Demo {
class Demo1<T1,T2>{
T2 age;
}
public static void main(String[] args) {
//泛型的拭除,消除警告可以用Object,泛型的拭除相当于Object,但是不完全等同于Object,因为不会进行编译检查
Demo1 demo = new Demo().new Demo1();
System.out.println(demo.age);//输出null
}
}
public class Demo {
static class Demo1<T1, T2> {
T1 age = (T1) "1";//T1 没有指定泛型类型,传入String类型参数编译错误;
}
public static void main(String[] args) {
//不会对T1进行类型检查
Demo1<Integer, Integer> demo = new Demo.Demo1<Integer,Integer>();
// demo.age 属于String类不属于Integer
if (demo.age instanceof Integer) {
System.out.println(1);
}
if (demo.age instanceof Object) {
System.out.println(2);
}
// if (demo.age instanceof String) {
// System.out.println(3);
// }//编译错误 因为demo.age类型是String类型的,指定的是Integer类型
}
}// 输出结果为2;
6)泛型没有多态,例如 :
public static Demo<Father> test(){
// return new Demo<Son>();//编译错误,Son和Father的类型不一致;
// return (Demo<Father>)(new Demo<Son>());//编译错误,Son和Father的类型不一致;
return new Demo<Father>();
}
public static void test(Demo<Father> d){
}
public static void main(String[] args) {
// test(new Demo<Son>());// 编译错误
}
}
class Demo<T>{
}
class Father{
}
class Son extends Father{
}
7)? extends 泛型上限注意是否是同一个类型 例如:
//public static void test(Demo<?> d){
//}
//public static void test(Demo<? extends Father> d){
//}//编译错误
8)没有泛型数组,不能创建泛型数组
---恢复内容结束---
标签:常用 print 包装类 创建 数组 return ext cas hash
原文地址:http://www.cnblogs.com/gg128/p/7468451.html