定义:
将对象的类型作为参数,指定到其他类或方法上,从而保证类型准换的安全性和稳定性,即参数化类型,那什么又是参数化类型呢?以前我们定义一个属性或者方法的时候,我们都会明确具体的类型,比如int、String、void等等,但是参数化之后,就不明确类型,只有在具体调用对象的时候,才传递实际类型实参,这就叫参数化类型,把类型明确的工作推迟到创建对象或调用方法的时候才去明确的特殊的类型,简而言之,就是在定义一个对象的时候没有赋予确切的参数类型,在实例化一个对象的时候传递确切的参数,类似于形参和实参的一种情况。
语法格式:
类1或者接口<类型实参> 对象=new 类2<类型实参>();
注意:类2可以是类1本身或者其子类或者是接口的实现类;类1类2的类型实参必须相同
示例如下:
package cn.kgc.review1113;
import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
/**
* @Author $(USER)
* @Date $(DATE)
* @Description 使用泛型修改集合
*/
public class CountriesInfo {
public static void main(String[] args) {
//创建集合对象,并将国家信息键值对放入集合
Map<String,String> countries =new HashMap<String,String>();
countries.put("China","中国");
countries.put("USA","美国");
countries.put("Japan","日本");
countries.put("France","法国");
//获取集合中存储元素个数
System.out.println(countries.size());
//获取集合中特风的key对应的value——返回的是Object类型,
// 需要强制类型转换
String country=countries.get("China");
System.out.println(country);
//获取集合中特定的key对应的value,如果找不到则返回null
String country2=countries.get("Mada");
System.out.println(country2);
//判断集合中是否存在某个国家——boolean值
System.out.println("是否存在键为china的国家:"+countries.containsKey("China"));
//删除某个特定key对应的键值对
System.out.println("是否存在键为USA的国家:"+countries.containsKey("USA"));
countries.remove("USA");
System.out.println("是否存在键为USA的国家:"+countries.containsKey("USA"));
System.out.println(countries.size());
//获取键的集合,值的集合,键值对的集合
System.out.println(countries.keySet());
System.out.println(countries.values());
System.out.println(countries);
//遍历Map,思路一:先遍历key,通过key——>value
Set<String> keys=countries.keySet();//获取Map中所有key,因为key无序且唯一,所以用Set类
//方法一.通过增强for循环
for(String key:keys){ //获取Map中的每一个key,用泛型定义后无需强制类型转换
String value=(String)countries.get(key);//根据Map中的每个key去获取对应的value
System.out.println(key+"--"+value);
}
//方法二:迭代器Iterator遍历key的集合(Set)
Iterator<String> itor=keys.iterator();
while(itor.hasNext()){
String key=itor.next();//获取Map中的每一个key,无需强制转换
String value=countries.get(key);//根据Map中的每个key去获取对应的value
System.out.println(key+"--"+value);
}
//方式二:获取Map中的所有键值对,然后在键值对中分别获取key和value
Set<Map.Entry<String,String>> set=countries.entrySet();//新方法entrySet():获取Map中所有的键值对
//遍历键值对的集合,把每个键值对拿出来,每个键值对都是Map.Entry()类型
for(Map.Entry<String,String> me:set){
String key=me.getKey();//获取出来键值对中的键
String value=me.getValue();获取出来键值对中的值
System.out.println(key+"--"+value);
}
}
}
泛型分类:
泛型的分类主要分为:泛型类、泛型接口、泛型方法
1. 泛型类
泛型类就是把泛型定义在类上,用户使用该类的时候,才把类型明确下来....这样的话,用户明确了什么类型,该类就代表着什么类型...用户在使用的时候就不用担心强转的问题,运行时转换异常的问题了。
类的定义:
/*
1:把泛型定义在类上
2:类型变量定义在类上,方法中也可以使用
*/
public class ObjectTool<T> {
private T obj;//变量的数据类型和泛型类所传递的数据类型一致
public T getObj() {//函数的返回类型和泛型类所传递的数据类型一致
return obj;
}
public void setObj(T obj) {
this.obj = obj;
}
}
测试代码:
public static void main(String[] args) {
//创建对象并指定元素类型为字符串类型
ObjectTool<String> tool = new ObjectTool<>();
tool.setObj("一只懒熊");
String s = tool.getObj();
System.out.println(s);
//创建对象并指定元素类型为整数类型
ObjectTool<Integer> objectTool = new ObjectTool<>();
/*
如果我在这个对象里传入的是String类型的,它在编译时期就通过不了了.
*/
objectTool.setObj(10);
int i = objectTool.getObj();
System.out.println(i);
}
泛型类的继承:泛型类是拥有泛型这个特性的类,它本质上还是一个Java类,那么它就可以被继承
那它是怎么被继承的呢?这里分两种情况
- 子类明确泛型类的类型参数变量
- 子类不明确泛型类的类型参数变量
情况1:子类明确泛型类的类型参数变量
//把泛型定义在接口上
public interface Inter<T> {
public abstract void show(T t);
}
//定义一个子类来实现接口
public class InterImpl implements Inter<String> {//子类明确泛型类的类型参数变量为String:
@Override
public void show(String s) {
System.out.println(s);
}
}
//测试代码
public class mingquefanxingcanshu {
public static void main(String[] args) {
Inter<String> i = new InterImpl();
i.show("hello java!");
}
}
情况2:子类不明确泛型类的类型参数变量
//把泛型定义在接口上
public interface Inter<T> {
public abstract void show(T t);
}
//定义一个子类来实现接口
public class InterImpl<T> implements Inter<T> {//实现类不明确泛型类的类型参数变量,实现类也要定义出<T>类型的
@Override
public void show(T s) {//子类方法也要继承类的数据类型T
System.out.println(s);
}
}
//测试代码
public class mingquefanxingcanshu {
public static void main(String[] args) {
Inter<String> i = new InterImpl();
i.show("hello java!");
}
}
注意:
- 实现类的要是重写父类的方法,返回值的类型是要和父类一样的!
- 类上声明的泛形只对非静态成员有效