泛型的引入
- 集合中的问题:
(1)存取时都应该以Object 方式,影响程序的读写操作
(2)取出时的强制类型转换操作麻烦,并可能出错 - 改进办法
在创建集合时就规定允许保存的类型,然后由编译器自动检测其加入元素的合法性,这样在取出元素时就不用再考虑类型转换的问题
泛型的作用和定义
- SE5之后开始引入
- 将原本确定不变的数据类型参数化
- 作为对JAVA原有类型的扩充,提高程序的类型安全、可维护性和可靠性
import java.util.*;
public class FanXing {
public static void main(String[] args){
Vector v =new Vector();
v.add("huang");
v.add("guo");
v.addElement("quan");
v.addElement(5);
v.addElement(new Date());
System.out.println(v.get(0));
System.out.println(v.get(1));
System.out.println(v.get(2));
System.out.println(v.get(3));
System.out.println(v.get(4));
for(int i=0;i<v.size();i++)
{
//Object o=v.get(i);
Object o=v.elementAt(i);
System.out.println(o);
}
String s=(String)v.get(1);
System.out.println(s.toUpperCase());
}
}
在Hashtable中的泛型应用(键值对的情况)
import java.util.*;
public class HashT {
public static void main(String[] args){
Hashtable<Integer,Person> ht=
new Hashtable<Integer,Person>();
ht.put(12,new Person("huang",40));
ht.put(13,new Person("guo",20));
Person p=ht.get(12);
p.print();
}
}
class Person{
private String name;
private int age;
public Person(String name,int age){
super(); this.name=name; this.age=age;}
public String getName(){ return name;}
public void setName(String name){ this.name=name; }
public int getAge(){ return age; }
public void setAge(int age){ this.age=age; }
public String toString(){
return "Person[name:"+name+",age:"+age+"]";
}
public void print() {System.out.println(toString());}
}
泛型的深入理解
- 只有泛型类才可启用泛型机制
泛型类:由类型参数修饰的类称为泛型类:
Public class Vector< E >{ } - 使用泛型后的通用性问题:通配符?的使用
- 泛型方法
Public T printf(T a,T b){}
Public T printf(T a,T b,int x){}//参数中可以有确定的类型
自定义一个泛型类
public class Teacher<T> {
private int id;
private T zj;
public Teacher(int id) {
super();
this.id = id;
}
public int getId() { return id; }
public void setId(int id) { this.id = id; }
public T getZj() { return zj; }
public void setZj(T zj) { this.zj = zj; }
public static void main(String[] args) {
Teacher<String> t=new Teacher(10);
t.setZj("shenfenzheng");
System.out.println(t.getZj());
Teacher<Integer> t1= new Teacher<Integer>(20);
t1.setZj(420106);
System.out.println(t1.getZj());
Teacher t2=new Teacher(30);
//系统自动调整为Object类型并会提出安全警告
System.out.println(t2.getZj());
}
}
通配符?的使用
import java.util.Vector;
public class Tongpei {
public static void main(String[] args)
{ Vector<String> v=new Vector<String>();
v.add("huang"); v.add("guo");
v.addElement("quan");
Vector<Integer> v1=new Vector<Integer>();
v1.add(1); v1.add(2);
v1.addElement(3);
printf(v);
printf(v1);
}
/*public static void printf(Vector <Integer> v)
{ for(Object o:v){ System.out.println(o); } }
public static void printf(Vector<Object> v)
{ for(Object o:v){ System.out.println(o); } }*/
public static void printf(Vector<?> v){
//v.add("huang");
//不能有这样的增加操作,因为不知道具体的类型
v.remove(1);//这样的操作是可以的 v.clear();
for(Object o:v){
System.out.println(o);
}
}
}
泛型方法
public class Fxff {
public static void main(String[] args){
Fxff f=new Fxff();
String s=f.eql("huang","huang");
Integer i=f.eql(100,200);
System.out.println(s);
System.out.println(i);
}
public <T> T eql(T a,T b){
if(a.equals(b)) return a;
else return null; }
}
public class Fxff <T>{
public static void main(String[] args){
Fxff f=new Fxff();
//String s=f.eql(“huang”,“huang”);错误
Object s=f.eql("huang","huang");
//Integer i=f.eql(100,200);错误
Object i=f.eql(100,200);
System.out.println(s); System.out.println(i);
}
public <T> T eql(T a,T b){
if(a.equals(b)) return a;
else return null; } }
class Fxff <T>{
//实例化类的时候指明泛型的具体类型
//public T eql(T a,T b)//参数类型非泛型类限定类型无法调用此方法
public <T> T eql(T a,T b)//参数类型非泛型类限定类型亦可调用此方法,输出结果非正常值
{ if(a.equals(b)) return a;
else return null;
}
public static void main(String[] args) {
Fxff<String> f=new Fxff<String>();
String s=f.eql(“huang”, “huang”);//可行,正常输出
Integer i=f.eql(100,200);//可行,null
System.out.println(s);
System.out.println(i);
}
}
import java.util.Vector;
public class Tongpei1 {
public static void main(String[] args)
{
Vector<String> v=new Vector<String>();
v.add("huang"); v.add("guo");
v.addElement("quan");
Vector<Integer> v1=new Vector<Integer>();
v1.add(1); v1.add(2);
v1.addElement(3);
//printf(v); //不可行,对通配符进行了限制,无法执行此方法
printf(v1);
}
public static void printf(Vector<? extends Number> v)
{
for(Object o:v)
{
System.out.print(o);
}
}
}
思考
利用JAVA的反射机制来“攻击”单例模式,并思考如何抵御这样的攻击?
package test;
class Elvis {
private static boolean flag = false;
private Elvis(){
}
private static class SingletonHolder{
private static final Elvis INSTANCE = new Elvis();
}
public static Elvis getInstance()
{
return SingletonHolder.INSTANCE;
}
public void doSomethingElse()
{
}
}
public class test{
public static void main(String[] args) {
Elvis e1=Elvis.getInstance();
Elvis e2=Elvis.getInstance();
System.out.println(e1==e2); //TRUE
}
}