泛型(即类型参数化,为了便于与一般的变量参数区别用<>将类型参数括起来,并且类型参数不能是基本类型必须是封装后的类,没有传入实际参数类型时,方法中的参数跟占位符有点类似)
<1>A:泛型类的声明跟一般类不同的是加了<>括起来的类型参数
泛型类的引用:
class 类名<类型参数列表> 变量名 = new 类名<类型参数列表>(形参列表)
类型参数列表中如果有多个类型参数要用逗号隔开
有时候需要对类型参数加以限制(例如:求平均数只能对数字,不能是字符串):
此时声明类时就应该指定一个上限界(限界可以是接口也可以是类,多个限界时用&分隔,限界可以是多个接口,但是其中最多只能有一个类,并且这个类必须为限界列表的第一个),让传递的所有的实例类型都必须是这个超类的直接或间接子类
eg:class 类名extends superclass>
B:静态成员变量不能是类型参数的实例:eg:static T ob;
<2>创建泛型方法:
[访问权限修饰符] [static] [final] <类型参数列表> 返回之类型 方法名(形参列表)
注:泛型方法可以定义为静态的也可以为实例的;虽然可以有静态泛型方法,但是不能在非泛型的静态方法体中使用类型参数
eg:
public class test {
T ob;
public test()
{
ob = null;
}
public test(T o)
{
ob = o;
}
//这里是非静态泛型方法,就不能在方法体中使用类型参数,会编译不通过
static void fun()
{
T o;
}
//这是一个静态泛型方法
static void showClassName(T o)
{
System.out.println(o.getClass().getName());
}
public static void main (String args[])
{
test ti = new test(110);
showClassName(ti);
}
}
<3>通配符参数
A:eg:
上面的例子将main方法改为:
public static void main (String args[])
{
test ti = new test(110);
test tf = new test(110.0f);
tf.showClassName(ti);//编译不通过
}
解决办法可以是通配符,使用如:泛型类名>,它是用来声明泛型类的变量的,而不能创建一个泛型类eg:class ABC>这种写法是不对的,通配符也可以有上限界。要将上面的例子该正确就需要:
static void showClassName(test> o)//test> o 含有通配符的泛型变量声明
{
System.out.println(o.getClass().getName());
}
public static void main (String args[])
{
test ti = new test(110);
test tf = new test(110.0f);
//这里Float型的数据写法必须为100.0f以与Double区别,否则将会产生编译不通过。
showClassName(ti);
}
B:判断一个对象ob是否是类ABC的实例如下:
ob intanceof ABC>//intanceof是一个二元操作符,它的作用就是测试它边的对象是否是右边类的实例,返回boolean类型数据。
<4>泛型类的继承
与一般类不同的是:如果父类是泛型类那么子类需要传递父类泛型参数,而且类型参数标识符必须一致,如果父类是非泛型类则不需要。
eg:
class testSub extends test
当然子类也可以声明自己的类型参数,只要用逗号与父类类型参数隔开,参数顺序可以根据自己的需要设置。
eg:
class testSub extends test
OR class testSub extends test
类型参数之间的继承与否关系,不会影响对应的泛型类之间的关系,也就是泛型类之间的继承关系与类型参数无关。
<5>泛型类对象强制类型转换必须是两者各个方面兼容,such as可以将子类对象强制转换为父类类型但不能将父类对象强制转换为子类类型;
<6>擦拭(代码被编译时,全部泛型类类型的信息会被删除,在程序体中会是使用类型参数的上限界替换类型参数,没有上限界时默认用Object替换),写完一个含有泛型的程序后在命令行输入反编译命令javap加类名,可以得到class文件中的信息,比较该信息与原程序信息,你会明白许多关于擦拭的意思。
eg:将test类中的static void fun()方法注释掉, 进行反编译后会出现:
Compiled from "test.java"
public class test extends java.lang.Object{
java.lang.Object ob;
public test();
public test(java.lang.Object);
java.lang.Object getOb();
static void showClassName(test);
public static void main(java.lang.String[]);
}
最好还是自己多用几个程序进行测试,这样体会更深。
这样也就给程序带来一些错误:如重载冲突,接口实现等。
JDK1.5才开始引入的泛型也有很多不足如:不能使用基本类型、泛型类异常、泛型数组、实例化参数类型对象这些都是会出现编译不通过的。
first time,希望各位能多多指教。
阅读(417) | 评论(0) | 转发(0) |