泛型:就是在定义类、接口、方法、方法的参数或成员变量时,指定它们的操作对象的类型为通用类型。具体使用的时候,将通用类型转换为指定类型使用。
自定义容器和泛型容器
import java.util.Arrays;
/*自定义一个容器*/
public class MyList {
private int size=0;//存放对象数量
private Object[] cache;//用来存放对象的数组
public MyList(){
cache=new Object[10];//默认容量为10
}
public void add(Object obj){//往数组中添加元素
int oldCapacity=cache.length;//先获取数组长度
if(oldCapacity==size){
Arrays.copyOf(cache,2*oldCapacity );//扩容2倍
}
cache[size++]=obj;
}
public Object get(int index){//返回数组中的元素
if(index>cache.length){
System.out.println("超出数组范围");
}
return cache[index];
}
public int size(){
return size;
}
}
import java.util.Arrays;
/*使用泛型容器*/
public class MyGenericList<E> {
private int size=0;//存放个数
private E[] cache;
public MyGenericList(){
cache=(E[]) new Object[10];//默认容量为10
}
public void add(E obj){
int oldCapacity=cache.length;
if(oldCapacity==size){
cache=Arrays.copyOf(cache,2*oldCapacity);
}
cache[size++]=obj;
}
public E get(int index){//返回指定下标的元素值
if(index>=cache.length){
System.out.println("超过元素数目");
}
return cache[index];
}
public int size(){
return size;
}
}
public class FanXingTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
MyList myList=new MyList();
myList.add(11);//将111转换成字符串
myList.add(111.3);//将111转换成字符串
myList.add("c");//将111转换成字符串
myList.add("1,1,1");
System.out.println("下标为3的元素时:"+myList.get(3));
System.out.println("元素个数为:"+myList.size());
int size=((myList==null)?0:myList.size());
for(int i=0;i<size;i++){
String str=myList.get(i).toString();
System.out.println(str.toUpperCase());//将所有字符转为大写
}
MyGenericList<String> m1=new MyGenericList<String>();//构建泛型容器m1,并指定容器中元素的类型为string
m1.add("sun");
m1.add("java");
int size1=((m1==null)?0:m1.size());
for(int i=0;i<size1;i++){
String str1=m1.get(i);
System.out.println(str1.toUpperCase());//将所有字符转为大写
}
}
}
运行结果:
下标为3的元素时:1,1,1
元素个数为:4
11
111.3
C
1,1,1
SUN
JAVA
泛型类和接口的定义及使用
泛型类的定义:
class MyGenericList<E>{ } //静态方法不能使用类的泛型参数,因为不确定参数类型
泛型接口的定义:
interface MyGenericTypeInterface<T>{ }
E:表示集合中的元素类型
K:表示键值对中的键类型
V:表示键值对中的值类型
T:表示其他所有类型
泛型类也可以继承和派生。如果一个类继承了泛型类,那么必须把类型参数传递给父类。
使用泛型类时,必须在创建的时候指定类型参数的值。
定义有界类型参数的泛型类(指定参数类型)(有上界的泛型):
class 类名<T extends 类型名>
public class SuperClass<T,U> {
private T t;
private U u;
public SuperClass(T t,U u){
this.t=t;
this.u=u;
}
public String toString(){
return (t.toString()+u.toString());
}
}
public class SubClass<T, U> extends SuperClass<T, U>{
public SubClass(T t, U u) { //泛型类的继承
super(t, u);
// TODO Auto-generated constructor stub
}
}
public class TpecialSubClass extends SuperClass<String, Integer>{
public TpecialSubClass(String str, Integer i) {
super(str, i);
// TODO Auto-generated constructor stub
}
}
/*有界类型参数
* 想让泛型参数为数值类型(Java.lang.Number类)的对象*/
public class Statistics<T extends Number> {
private T[]arrays;
public Statistics(T[] arrays){
this.arrays=arrays;
}
public double Rsum(){
double sum=0.0;
for(int i=0;i<arrays.length;i++){
sum=arrays[i].doubleValue()+sum;
}
return sum;
}
}
public class FTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
TpecialSubClass t1=new TpecialSubClass("zz", 12);//子类指定参数类型(String , Integer)
TpecialSubClass t2=new TpecialSubClass("cc", Integer.valueOf(56));
System.out.println(t1.toString());
System.out.println(t2.toString());
SubClass s=new SubClass("String", Double.valueOf(12.36));//任意参数类型
System.out.println(s.toString());
Statistics s2=new Statistics(new Integer []{2,5,85,6,45,12});
System.out.println(s2.Rsum());
}
}
运行结果:
zz12
cc56
String12.36
155.0
泛型方法
定义语句:
访问控制符 [修饰符] <类型参数列表> 返回值类型 方法名(参数列表)
泛型方法主要用于定义类中需要具有泛型能力的静态方法
public class GenericMethodTest {
public static void main(String[] args) {
// TODO Auto-generated method stub
GenericMethod.max(100,123,23,96.32,999.32);
}
}
class GenericMethod{
@SafeVarargs
public static <T extends Number>void max(T...args){ //参数为T型数组 名字args
@SuppressWarnings("unchecked")
T temp=(T)Integer.valueOf(0);
System.out.println(temp);
for(T t:args){ //数组类型:T 变量名:t(自定义) 数组名:args
if(t.doubleValue()>temp.doubleValue()){
temp=t;
}
}
System.out.println(temp);
}
}
运行结果
0
999.32
类型参数的通配符
通配符“?”
通配符上界的设置语法:
<? extends Number>:参数类型必须是Number类或其子类的实例
<? super Number>:参数类型必须是Number类或其父类的实例
泛型的局限性
1.不能使用基本类型的类型参数
2.静态成员无法使用类型参数
3.不能使用泛型类异常
4.不能使用泛型数组
5.不能实例化参数类型对象