【Java基础】泛型的一些总结
什么是泛型
泛型其实可以理解为一种广泛的类型,啥类型都型,当然,这种泛是指定义时可以广泛,但是使用时必须确定类型。也就是说,当不清楚未来使用哪种类型时,定义为泛型。可以支持泛型类,泛型接口,泛型方法,泛型成员变量。
泛型的好处
- 泛型可以将类型作为参数进行传递,即类型可以像参数一样实现参数化。
- 泛型能提高代码的重用。
- 在编译的时候检查类型安全,把运行期的问题提前展现出来。
- 泛型中的强制转换都是自动和隐式的
下面用几个示例来表明这几种好处:
下面的代码表示的是代码重用的案例,几个传入不同类型的a都可以用泛型T表示。
public void show(int a){
System.out.println(a);
} public void show(Boolean a){
System.out.println(a);
}
public void show(String a){
System.out.println(a);
} public void show(T a){
System.out.println(a);
}
下面这段代码在编译期间是不会出错的,因为集合中可以传入任何对象,但是一运行就会出错,因为后面遍历时进行强制转换为Integer,String是不能强转为Integer的。
List s = new ArrayList();
s.add(1);
s.add(2);
s.add("hello");
Iterator it = s.iterator();
int sum = 0;
while (it.hasNext()){
Integer i = (Integer) it.next();
sum += i;
}
但是由于ArrayList是泛型类,如果在定义的时候提前确定将来要存储在List中的类型,则可以提前提示出错误,这个就类似我们定义数组,刚开始就确定了数组的类型。
自动强制用的最多的地方就是在Iterator时规定了迭代的类型,所以在遍历时不用做强转工作,会自动强转。
List<Integer> s = new ArrayList(); s.add(1);
s.add(2);
// s.add("hello");
Iterator<Integer> it = s.iterator();
int sum = 0;
while (it.hasNext()){
// Integer i = (Integer) it.next();
sum += it.next();//由于Integer中规定了类型,这里会自动强制转换
}
泛型类(Object和泛型类的区别--思考引入泛型的原因)
Object也可以代替任何类型,那Object是否可以取代泛型呢?接下来看一个示例程序:
public class Test {
public static void main(String[] args) {
Animal animal = new Animal();
animal.setAttr(3);
Integer age = (Integer) animal.getAttr();
System.out.println(age); System.out.println("---------------------");
animal.setAttr("dog");
String kind = (String) animal.getAttr();
System.out.println(kind); System.out.println("---------------------");
animal.setAttr("kity");
Integer name = (Integer) animal.getAttr();//不按常规出牌,编译不报错
System.out.println(name); }
} class Animal {
private Object attr; public Animal() {
} public Object getAttr() {
return attr;
} public void setAttr(Object attr) {
this.attr = attr;
}
}
明显Test中最后一段设置姓名是String,但是做强转可能没搞清楚,偏偏转到Integer了,但是这个时候是不会报错的,因为编译期间Object是可以向子类Integer向下转型的。但是运行时就会报错,所以利用Object来写这种程序是不安全的。但是如果将Object替换为泛型,则会在编译期间就会报错。
上述代码,如果将Animal定义为泛型类,即将Object都替换为泛型支持,并在Animal后面加上尖括号<T>,于此同时保持测试代码不变,依然编译期间不会报错,这说明,如果不指定T的类型,默认应该还是将T换成了Object。
但是,泛型类的使用规则是需要你定义的时候就规定将来的类型的,在定义时讲T确定为Integer后,上述代码有三行编译出错。
public class Test {
public static void main(String[] args) {
Animal<Integer> animal = new Animal<>();
animal.setAttr(3);
Integer age = (Integer) animal.getAttr();
System.out.println(age); System.out.println("---------------------");
animal.setAttr("dog");//编译不通过
String kind = (String) animal.getAttr();//编译不通过
System.out.println(kind); System.out.println("---------------------");
animal.setAttr("kity");//编译不通过
Integer name = (Integer) animal.getAttr();
System.out.println(name); }
} class Animal<T> {
private T attr; public Animal() {
} public T getAttr() {
return attr;
} public void setAttr(T attr) {
this.attr = attr;
}
}
泛型方法
泛型类有一个特点,就是需要在实例化类的时候明确泛型的类型,不然有警告(不然就是当作Object),一旦定义了,接下来类中的所有泛型的T都确定了。也就是说如果实例化的时候将T定义为String,则类中所有的T都是String,这样不是太灵活。所以引入了泛型方法。
泛型方法的定义特征:public static <T> List<T> asList(T... a)
这里用Arrays中的asList方法来举例说明,泛型方法是将以前泛型类中的<T>放到了方法返回值前面。这样asList方法以后可以接受任何类型的传参了。
ps:这篇文章对泛型方法进行了更深入的总结http://www.cnblogs.com/iyangyuan/archive/2013/04/09/3011274.html
泛型接口
泛型接口和泛型类类似,只是实现泛型接口的类一般也是继续泛型下去,如若不然,则泛型接口的灵活性就没有被突显了。
public interface Animal<T> {
public abstract void show(T a);
}
public class Dog<T> implements Animal<T>{ @Override
public void show(T a) {
System.out.println(a);
}
}
泛型的高级运用-通配符
1. ?: 任意类型,如果没有明确,那么就是Object以及任意的Java类了
2. ? extends E: 向下限定,E及其子类
3. ? super E: 向上限定,E极其父类
public class GenericDemo {
public static void main(String[] args) {
// 泛型如果明确的写的时候,前后必须一致
Collection<Object> c1 = new ArrayList<Object>();
// Collection<Object> c2 = new ArrayList<Animal>();
// Collection<Object> c3 = new ArrayList<Dog>();
// Collection<Object> c4 = new ArrayList<Cat>(); // ?表示任意的类型都是可以的
Collection<?> c5 = new ArrayList<Object>();
Collection<?> c6 = new ArrayList<Animal>();
Collection<?> c7 = new ArrayList<Dog>();
Collection<?> c8 = new ArrayList<Cat>(); // ? extends E:向下限定,E及其子类
// Collection<? extends Animal> c9 = new ArrayList<Object>();
Collection<? extends Animal> c10 = new ArrayList<Animal>();
Collection<? extends Animal> c11 = new ArrayList<Dog>();
Collection<? extends Animal> c12 = new ArrayList<Cat>(); // ? super E:向上限定,E极其父类
Collection<? super Animal> c13 = new ArrayList<Object>();
Collection<? super Animal> c14 = new ArrayList<Animal>();
// Collection<? super Animal> c15 = new ArrayList<Dog>();
// Collection<? super Animal> c16 = new ArrayList<Cat>();
}
} class Animal {
} class Dog extends Animal {
} class Cat extends Animal {
}
【Java基础】泛型的一些总结的更多相关文章
- 一天一个Java基础——泛型
这学期的新课——设计模式,由我仰慕已久的老师传授,可惜思维过快,第一节就被老师挑中上去敲代码,自此在心里烙下了阴影,都是Java基础欠下的债 这学期的新课——算法设计与分析,虽老师不爱与同学互动式的讲 ...
- Java 基础 -- 泛型、集合、IO、反射
package com.java.map.test; import java.util.ArrayList; import java.util.Collection; import java.util ...
- java基础-泛型举例详解
泛型 泛型是JDK5.0增加的新特性,泛型的本质是参数化类型,即所操作的数据类型被指定为一个参数.这种类型参数可以在类.接口.和方法的创建中,分别被称为泛型类.泛型接口.泛型方法. 一.认识泛型 在没 ...
- Java基础 - 泛型详解
2022-03-24 09:55:06 @GhostFace 泛型 什么是泛型? 来自博客 Java泛型这个特性是从JDK 1.5才开始加入的,因此为了兼容之前的版本,Java泛型的实现采取了&quo ...
- java基础-泛型3
浏览以下内容前,请点击并阅读 声明 8 类型擦除 为实现泛型,java编译器进行如下操作进行类型擦除: 如果类型参数有限制则替换为限制的类型,如果没有则替换为Object类,变成普通的类,接口和方法. ...
- java基础 泛型
泛型的存在,是为了使用不确定的类型. 为什么有泛型? 1. 为了提高安全 2. 提高代码的重用率 (自动 装箱,拆箱功能) 一切好处看代码: package test1; import java.la ...
- java基础-泛型2
浏览以下内容前,请点击并阅读 声明 6 类型推测 java编译器能够检查所有的方法调用和对应的声明来决定类型的实参,即类型推测,类型的推测算法推测满足所有参数的最具体类型,如下例所示: //泛型方法的 ...
- java基础-泛型1
浏览以下内容前,请点击并阅读 声明 泛型的使用能使类型名称作为类或者接口定义中的参数,就像一般的参数一样,使得定义的类型通用性更强. 泛型的优势: 编译具有严格的类型检查 java编译器对于泛型代码的 ...
- Java基础---泛型、集合框架工具类:collections和Arrays
第一讲 泛型(Generic) 一.概述 1.JDK1.5版本以后出现的新特性.用于解决安全问题,是一个类型安全机制. 2.JDK1.5的集合类希望在定义集合时,明确表明你要向集合中装入那种类 ...
- Java基础——泛型
一.定义 泛型(generic)是指参数化类型的能力.可以定义带泛型类型的类或方法,随后编译器会用具体的类型来替换它(泛型实例化).使用泛型的主要优点是能够在编译时,而不是在运行时检测出错误.它是jd ...
随机推荐
- 【dynamic】简化反射简单尝试
最近在自己瞎整设计自己的数据访问层(纯属深入了解C#用),遇到了反射.网传反射性能很差,可是我们项目中也有功能用到了反射,总体来说还不错(小项目).由于居安思危的感觉越发沉重,不得不去打破传统,去寻求 ...
- 最近在无线USB网卡投入比较大
第一次(40): 乐光N18网卡 17 5米USB延长线 10 DVD2 3 运费10 第二次(30): 8187L主板13 5DB/6DB全向天线 5 外壳FREE 运费12 第三次(20): 8D ...
- 调用windows api 获取系统分辨率
c++中: int cxScreen,cyScreen; cxScreen=GetSystemMetrics(SM_CXSCREEN); cyScreen=GetSystemMetrics(SM_CY ...
- Centos 6.2 32位机器安装新的JDK和Weblogic
一.首先卸载自带的JDK 1.查看自带的java版本. root@admin]#java -version java version "1.6.0" OpenJDK Runtime ...
- python 读取机器信息
本人最近新学python ,用到关于机器的相关信息,经过一番研究,从网上查找资料,经过测试,总结了一下相关的方法. # -*- coding: UTF8 -*- import os import wi ...
- delphi xe5 android iny绿色版+最新SDK/NDK安装方法
转自: http://bbs.2ccc.com/topic.asp?topicid=438595 首先感谢iny的绿色版,因为我的精简Win7 32位安装原版镜像4.63G过程正常,但是编译出错,后来 ...
- 关于\t
tail -n 10000 sample_dbl.txt | python sitemap.py | sort -k 1 -t $'\t' | python sitecombiner.py > ...
- 朴素贝叶斯文本分类java实现
package com.data.ml.classify; import java.io.File; import java.util.ArrayList; import java.util.Coll ...
- css3创建动画
@keyframes ico{ 0% { top: -100%; } 100%{ top:4%; } } @-webkit-keyframes ico{ 0% { top: -100%; } 100% ...
- [转载]C# 判断字符是否中文还是英文
private static bool IsHanZi(string ch) { byte[] byte_len = System.Text.Encoding.Default.GetBytes(ch) ...