泛型的意义:
解决数据类型的安全性问题,
主要用法:类声明时通过一个标识表示类中属性的类型或方法返回值类型或入参类型
package Generic;
public class Point<T> { //T是tyep的简称,代表可以是任意的标识符号
private T var; //变量类型有外部决定;
public T getVar(){ //返回值由外部决定
return var;
}
public void setVar(T var){ //设置的类型有外部决定
this.var = var;
}
}
上面的T是表示此类型是由外部调用本类时指定,可以是任意的字母如<A>、<B>,之所以用<T>,是因为T是type的缩写,表示类型。
实战:
1):用泛型修改代码
package Generic;
public class PointModify<T> { //指定泛型类型
private T x; //表示x坐标,具体类型由外部指定
private T y; //表示y坐标,具体类型由外部指定
public T getX() {
return x;
}
public void setX(T x) {
this.x = x;
}
public T getY() {
return y;
}
public void setY(T y) {
this.y = y;
}
public static void main(String[] args) {
PointModify<Integer> p = new PointModify<Integer>();//定义pointModify对象,指定Integer为泛型类型
p.setX(10);//设置整数,自动装箱
p.setY(30);
System.out.println("整数表示,X坐标:"+p.getX());//输出信息,自动拆箱
System.out.println("整数表示,Y坐标:"+p.getY());
}
}
结果:
整数表示,X坐标:10
整数表示,Y坐标:30
2):指定多个泛型类型
package Generic;
public class PointMulti<K,V> {//此处设置两个泛型类型
private K key;//类型由外部指定
private V value;
public K getKey() {
return key;
}
public void setKey(K key) {
this.key = key;
}
public V getValue() {
return value;
}
public void setValue(V value) {
this.value = value;
}
public static void main(String[] args) {
PointMulti<String,Integer> p = new PointMulti<String,Integer>();
p.setKey("java");
p.setValue(2018);
System.out.println("课程:key="+p.getKey());
System.out.println("时间:value="+p.getValue());
}
}
结果:
课程:key=java
时间:value=2018
3):匹配任意类型的通配符("?")
Info<?>:表示可以使用任意的泛型类型对象
package Generic;
/**
* 通配符?
*
*/
public class PointDemo<T> {
private T var; //变量类型有外部决定;
public T getVar(){ //返回值由外部决定
return var;
}
public void setVar(T var){ //设置的类型有外部决定
this.var = var;
}
public static void main(String[] args) {
PointDemo<String> p = new PointDemo<String>();
p.setVar("java");
fun(p);
}
public static void fun(PointDemo<?> temp){
System.out.println("通配符使用--->输出内容:"+temp);
}
}
结果:
通配符使用--->输出内容:Generic.PointDemo@c3c749
4):受限泛型
4.1):泛型上限:使用extends关键字声明,表示泛型可能是所指定的类型或是其子类。
package relation;
/**
* 通配符?
* @author 陈磊
*
*/
public class PointDemo1<T> {
private T var; //变量类型有外部决定;
public T getVar(){ //返回值由外部决定
return var;
}
public void setVar(T var){ //设置的类型有外部决定
this.var = var;
}
public static void main(String[] args) {
PointDemo1<String> p1 = new PointDemo1<String>();//声明String对象
PointDemo1<Integer> p2 = new PointDemo1<Integer>();//声明Integer对象
p1.setVar("java");
p2.setVar(2018);
fun(p1);
fun(p2);
}
public static void fun(PointDemo1<?extends Object> temp){//设置泛型上限
System.out.println("通配符使用--->输出内容:"+temp);
}
public String toString(){
return this.var.toString();
}
}
结果:
通配符使用--->输出内容:java
通配符使用--->输出内容:2018
4.2):泛型下限:使用super关键字声明,表示泛型可能是所指定的类型或是其父类或Object类。
package relation;
/**
* 通配符?
* @author 陈磊
*
*/
public class PointDemo2<T> {
private T var; //变量类型有外部决定;
public T getVar(){ //返回值由外部决定
return var;
}
public void setVar(T var){ //设置的类型有外部决定
this.var = var;
}
public static void main(String[] args) {
PointDemo2<String> p1 = new PointDemo2<String>();//声明String对象
PointDemo2<Object> p2 = new PointDemo2<Object>();//声明Integer对象
p1.setVar("java");
p2.setVar(2018);
fun(p1);
fun(p2);
}
public static void fun(PointDemo2<?super String> temp){//设置泛型下限,只能接受String或Object类
System.out.println("通配符使用--->输出内容:"+temp);
}
public String toString(){
return this.var.toString();
}
}
结果:
通配符使用--->输出内容:java
通配符使用--->输出内容:2018
5):泛型的实战
package Generic.demo;
public interface Info {//定义一个表示接口,此接口没有任何方法
}
package Generic.demo;
public class Contact implements Info {
private String address;
private String telphone;
private String zipcode;
public Contact(String address, String telphone, String zipcode) {
super();
this.address = address;
this.telphone = telphone;
this.zipcode = zipcode;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getTelphone() {
return telphone;
}
public void setTelphone(String telphone) {
this.telphone = telphone;
}
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
@Override
public String toString() {
return "联系方式:" +"\n"+
"\t|-联系地址:" + address + "\n"+
"\t|-联系电话:" + telphone+"\n"+
"\t|-邮政编码:" + zipcode ;
}
}
package Generic.demo;
public class Introduction implements Info {
private String name;
private String sex;
private int age;
public Introduction(String name, String sex, int age) {
super();
this.name = name;
this.sex = sex;
this.age = age;
}
public String getAddress() {
return name;
}
public void setAddress(String name) {
this.name = name;
}
public String getTelphone() {
return sex;
}
public void setTelphone(String sex) {
this.sex = sex;
}
public int getZipcode() {
return age;
}
public void setZipcode(int age) {
this.age = age;
}
@Override
public String toString() {
return "基本信息:" +"\n"+
"\t|-姓名:" + name + "\n"+
"\t|-性别:" + sex+"\n"+
"\t|-年龄:" + age ;
}
}
package Generic.demo;
public class Person<T extends Info> {
private T infoT;
public T getInfoT() {
return infoT;
}
public void setInfoT(T infoT) {
this.infoT = infoT;
}
public Person(T infoT) {
this.infoT = infoT;
}
@Override
public String toString() {
return infoT.toString();
}
public static void main(String[] args) {
Person<Contact> per = null;
per = new Person<Contact>(new Contact("北京市", "010", "100088"));
System.out.println(per);
}
}
结果:
联系方式:
|-联系地址:北京市
|-联系电话:010
|-邮政编码:100088
要点:
- 泛型使程序操作更安全,避免发生类转换异常
- 使用通配符“?”接受全部的泛型类型对象。
- 通过<? extends 类>设置泛型上限,通过<? super 类>设置泛型下限
- 在程序中,没有方法的接口,一般称该接口为标识接口。