Java 学习笔记:泛型(一)
2008-04-16 01:58
495 查看
一. 为什么需要泛型
在面向对象编程语言中,多态算是一种泛型。但是多态一般的做法是把子类赋给其基类,以此实现灵活性更高的代码 。但是受限于Java的单继承机制,代码的灵活性并不能得到多大的提高。于是,设计模式中推荐的法则是:面向接口编程。可是,问题还是没有得到很好的解决,因为即使是面向接口编程对于设计类库这种需求在某种程度上来说还是太过苛刻了(试想一下如果你需要写一个容器类,但是容器里面的元素要求实现某个特定的接口,这样是不是会变得有点麻烦)。泛型是Java SE5的一个新特性,凭借泛型,java实现了参数化类型的概念。
对比一下以下代码
public class GenericTest1 ...{
private Object a;
public GenericTest1(Object a)
...{
this.a = a;
}
public Object getA() ...{
return a;
}
public void setA(Object a) ...{
this.a = a;
}
public static void main(String[] args)
...{
GenericTest1 g1 = new GenericTest1("1");
String str = (String)g1.getA(); ①
g1.setA(1); ②
Integer x = (Integer) g1.getA();
}
}
public class GenericTest2 <T> ...{
private T a;
public GenericTest2(T a)
...{
this.a = a;
}
public T getA() ...{
return a;
}
public void setA(T a) ...{
this.a = a;
}
public static void main(String[] args)
...{
GenericTest2<String> g2 = new GenericTest2<String>("1");
String str = g2.getA(); ①
// 编译时错误
g2.setA(1); ②
}
}
从两段程序的①可以看出,使用泛型之后我们不再需要做类型的转换,因为编译器会帮你处理一切细节。从程序的②可以看出,当我们使用泛型之后编译器会自动进行类型检查。
所以,使用泛型之后我们可以得到更方便、更安全的代码。
二.泛型接口
泛型也可以应用于接口。简单的例子如下:
public interface GenericInterface <T> ...{
T next();
}
public class GenericTest3 implements GenericInterface<Integer> ...{
private int[] a;
private int size;
private int pos = 0;
private int addPos = 0;
public GenericTest3(int sz)
...{
this.size = sz;
a = new int[sz];
}
public Integer next()
...{
if ( pos > addPos - 1 )
...{
pos = 0;
}
return a[pos++];
}
public boolean hasNext()
...{
return !(pos == addPos);
}
public boolean add(int value)
...{
if ( addPos >= size )
...{
return false;
}
else
...{
a[addPos++] = value;
return true;
}
}
public int getSize() ...{
return size;
}
}
public class GenericTest4 implements GenericInterface<String> ...{
private String[] a;
private int size;
private int pos = 0;
private int addPos = 0;
public GenericTest4(int sz)
...{
this.size = sz;
a = new String[sz];
}
public String next()
...{
if ( pos > addPos - 1 )
...{
pos = 0;
}
return a[pos++];
}
public boolean hasNext()
...{
return !(pos == addPos);
}
public boolean add(String value)
...{
if ( addPos >= size )
...{
return false;
}
else
...{
a[addPos++] = value;
return true;
}
}
public int getSize() ...{
return size;
}
}
public class GenericTest5 ...{
public static void main(String[] args)
...{
GenericTest3 g3 = new GenericTest3(3);
GenericTest4 g4 = new GenericTest4(4);
String[] values = "a,b,c,d,e,f,g,h,i,j,k,l".split(",");
for (int i = 0; i < g3.getSize(); i++)
...{
g3.add(i);
}
for (int i = 0; i < g4.getSize(); i++)
...{
g4.add(values[i]);
}
while(g3.hasNext())
...{
System.out.println(g3.next());
}
while(g4.hasNext())
...{
System.out.println(g4.next());
}
}
}
这里需要注意一点:基本类型不能作为泛型的类型参数。GenericTest3里面的元素为int,但是参数需要用Integer。
在面向对象编程语言中,多态算是一种泛型。但是多态一般的做法是把子类赋给其基类,以此实现灵活性更高的代码 。但是受限于Java的单继承机制,代码的灵活性并不能得到多大的提高。于是,设计模式中推荐的法则是:面向接口编程。可是,问题还是没有得到很好的解决,因为即使是面向接口编程对于设计类库这种需求在某种程度上来说还是太过苛刻了(试想一下如果你需要写一个容器类,但是容器里面的元素要求实现某个特定的接口,这样是不是会变得有点麻烦)。泛型是Java SE5的一个新特性,凭借泛型,java实现了参数化类型的概念。
对比一下以下代码
public class GenericTest1 ...{
private Object a;
public GenericTest1(Object a)
...{
this.a = a;
}
public Object getA() ...{
return a;
}
public void setA(Object a) ...{
this.a = a;
}
public static void main(String[] args)
...{
GenericTest1 g1 = new GenericTest1("1");
String str = (String)g1.getA(); ①
g1.setA(1); ②
Integer x = (Integer) g1.getA();
}
}
public class GenericTest2 <T> ...{
private T a;
public GenericTest2(T a)
...{
this.a = a;
}
public T getA() ...{
return a;
}
public void setA(T a) ...{
this.a = a;
}
public static void main(String[] args)
...{
GenericTest2<String> g2 = new GenericTest2<String>("1");
String str = g2.getA(); ①
// 编译时错误
g2.setA(1); ②
}
}
从两段程序的①可以看出,使用泛型之后我们不再需要做类型的转换,因为编译器会帮你处理一切细节。从程序的②可以看出,当我们使用泛型之后编译器会自动进行类型检查。
所以,使用泛型之后我们可以得到更方便、更安全的代码。
二.泛型接口
泛型也可以应用于接口。简单的例子如下:
public interface GenericInterface <T> ...{
T next();
}
public class GenericTest3 implements GenericInterface<Integer> ...{
private int[] a;
private int size;
private int pos = 0;
private int addPos = 0;
public GenericTest3(int sz)
...{
this.size = sz;
a = new int[sz];
}
public Integer next()
...{
if ( pos > addPos - 1 )
...{
pos = 0;
}
return a[pos++];
}
public boolean hasNext()
...{
return !(pos == addPos);
}
public boolean add(int value)
...{
if ( addPos >= size )
...{
return false;
}
else
...{
a[addPos++] = value;
return true;
}
}
public int getSize() ...{
return size;
}
}
public class GenericTest4 implements GenericInterface<String> ...{
private String[] a;
private int size;
private int pos = 0;
private int addPos = 0;
public GenericTest4(int sz)
...{
this.size = sz;
a = new String[sz];
}
public String next()
...{
if ( pos > addPos - 1 )
...{
pos = 0;
}
return a[pos++];
}
public boolean hasNext()
...{
return !(pos == addPos);
}
public boolean add(String value)
...{
if ( addPos >= size )
...{
return false;
}
else
...{
a[addPos++] = value;
return true;
}
}
public int getSize() ...{
return size;
}
}
public class GenericTest5 ...{
public static void main(String[] args)
...{
GenericTest3 g3 = new GenericTest3(3);
GenericTest4 g4 = new GenericTest4(4);
String[] values = "a,b,c,d,e,f,g,h,i,j,k,l".split(",");
for (int i = 0; i < g3.getSize(); i++)
...{
g3.add(i);
}
for (int i = 0; i < g4.getSize(); i++)
...{
g4.add(values[i]);
}
while(g3.hasNext())
...{
System.out.println(g3.next());
}
while(g4.hasNext())
...{
System.out.println(g4.next());
}
}
}
这里需要注意一点:基本类型不能作为泛型的类型参数。GenericTest3里面的元素为int,但是参数需要用Integer。
相关文章推荐
- Java学习笔记-泛型
- 黑马程序员----Java集合框架学习笔记2 Map-工具类-泛型
- Java张孝祥视频 学习笔记 泛型
- Java学习笔记-泛型及类型擦除
- Java学习笔记之泛型(一):集合中的泛型
- Java ---学习笔记(泛型)
- Android(java)学习笔记91:泛型接口的概述和使用
- java泛型的学习笔记[2]—实际使用
- [学习笔记] Java核心技术 卷一:基础知识 泛型程序设计(五)
- Java学习笔记(泛型)
- java学习笔记08--泛型
- java 泛型学习笔记
- JAVA学习笔记之泛型接口
- Bravo!Java学习笔记(2)---泛型程序设计
- Java学习笔记(七):内部类、静态类和泛型
- 我的java学习笔记(10)关于泛型数组列表
- 黑马程序员—Java基础加强学习笔记之泛型
- Thinking in java学习笔记—泛型(擦除)
- java 学习笔记—— 自定义泛型、枚举与注释
- java学习笔记00_泛型的(完成)