http://blog.csdn.net/wangjian223344/article/details/16846165
1.泛型的引入:
为什么要用泛型?
比如现在要设计一个坐标的方法
坐标有几种表示方法:
1.整数:x=20,y=20
2.小数:x=20.2,y=20.2
3.字符串:x=东京180,y="北纬210"
看到这里我们是不是在想,要建立一个point类是,里面定义一个方法,来接收这三种数据,但是数据有三种,那么就只有用Object来接收了。因为Object可以接收任何数据,发生向上转型。。。
实现的思路:
代码:
//整数接收
class
Point{
private
Object
x
;
private
Object
y
;
public
Object getX() {
return
x
;
}
public
void
setX(Object x) {
this
.
x
= x;
}
public
Object getY() {
return
y
;
}
public
void
setY(Object y) {
this
.
y
= y;
}
}
public
class
PointTest {
public
static
void
main(String[] args) {
Point point=
new
Point();
//整数接收
point.setX(20);
point.setY(20);
int
x=(Integer)point.getX();
int
y=(Integer)point.getY();
System.
out
.println(
"x坐标:"
+x);
System.
out
.println(
"y坐标:"
+y);
}
}
结果:
x坐标:20
y坐标:20
//小数接收
class
Point{
private
Object
x
;
private
Object
y
;
public
Object getX() {
return
x
;
}
public
void
setX(Object x) {
this
.
x
= x;
}
public
Object getY() {
return
y
;
}
public
void
setY(Object y) {
this
.
y
= y;
}
}
public
class
PointTest {
public
static
void
main(String[] args) {
Point point=
new
Point();
//整数接收
point.setX(20.2);
point.setY(20.2);
double
x=(Double)point.getX();
double
y=(Double)point.getY();
System.
out
.println(
"x坐标:"
+x);
System.
out
.println(
"y坐标:"
+y);
}
}
结果:
x坐标:20.2
y坐标:20.2
//字符转接收
class
Point{
private
Object
x
;
private
Object
y
;
public
Object getX() {
return
x
;
}
public
void
setX(Object x) {
this
.
x
= x;
}
public
Object getY() {
return
y
;
}
public
void
setY(Object y) {
this
.
y
= y;
}
}
public
class
PointTest {
public
static
void
main(String[] args ) {
Point point=
new
Point();
//整数接收
point.setX(
"东经120"
);
point.setY(
"北纬60"
);
String x=(String)point.getX();
String y=(String)point.getY();
System.
out
.println(
"x坐标:"
+x);
System.
out
.println(
"y坐标:"
+y);
}
}
结果:
x坐标:东经120
y坐标:北纬60
好像这样是实现了我们想要的结果,那么来看看这段代码:
class
Point{
private
Object
x
;
private
Object
y
;
public
Object getX() {
return
x
;
}
public
void
setX(Object x) {
this
.
x
= x;
}
public
Object getY() {
return
y
;
}
public
void
setY(Object y) {
this
.
y
= y;
}
}
public
class
PointTest {
public
static
void
main(String[] args) {
Point point=
new
Point();
//整数接收
point.setX(123);
point.setY(
"北纬60"
);//这里是用Object来接收的,所以可以接收任何类型
int
x=(Integer)point.getX();
int
y=(Integer)point.getY();
System.
out
.println(
"x坐标:"
+x);
System.
out
.println(
"y坐标:"
+y);
}
}
结果:
Exception in thread "main"
java.lang.ClassCastException
: java.lang.String cannot be cast to java.lang.Integer
at test.PointTest.main(
PointTest.java:42
)
所以,这样为们才有了现在的泛型
泛型代码:
class
Point1<T>{
//声明一个泛型类
private
T
var
;
//声明一个泛型变量
private
T
Yar
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
public
T getYar() {
return
Yar
;
}
public
void
setYar(T yar) {
Yar
= yar;
}
}
public
class
PointTest1 {
public
static
void
main(String[] args) {
Point1<Object> point=
new
Point1<Object>();
point.setVar(20);
point.setYar(
"北纬"
);
System.
out
.println(
"x坐标"
+point.getVar());
System.
out
.println(
"y坐标"
+point.getYar());
}
}
结果:
x坐标20
y坐标北纬
2.泛型的构造方法
class
Point1<T>{
//声明一个泛型类
private
T
var
;
//声明一个泛型变量
private
T
Yar
;
public
T getVar() {
return
var
;
}
public
Point1(T var, T yar) {
this
.
var
= var;
Yar
= yar;
}
public
void
setVar(T var) {
this
.
var
= var;
}
public
T getYar() {
return
Yar
;
}
public
void
setYar(T yar) {
Yar
= yar;
}
}
public
class
PointTest1 {
public
static
void
main(String[] args) {
Point1<Object> point=
new
Point1<Object>(20,
"北纬"
);
//point.setVar(20);
// Point1<String> point1=new Point1<String>();
// point.setYar("北纬");
System.
out
.println(
"x坐标"
+point.getVar());
System.
out
.println(
"y坐标"
+point.getYar());
}
}
结果:
x坐标20
y坐标北纬
3.指定多个泛型
class
Point1<T,K>{
//声明一个泛型类
private
T
var
;
//声明一个泛型变量
private
K
Yar
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
public
K getYar() {
return
Yar
;
}
public
void
setYar(K yar) {
Yar
= yar;
}
public
Point1(T var, K yar) {
this
.
var
= var;
Yar
= yar;
}
}
public
class
PointTest1 {
public
static
void
main(String[] args) {
Point1<Integer,String> point=
new
Point1<Integer,String>(20,
"北纬"
);
//point.setVar(20);
// Point1<String> point1=new Point1<String>();
// point.setYar("北纬");
System.
out
.println(
"x坐标"
+point.getVar());
System.
out
.println(
"y坐标"
+point.getYar());
}
}
结果:
x坐标20
y坐标北纬
4.泛型的安全警告
class
Point1<T,K>{
//声明一个泛型类
private
T
var
;
//声明一个泛型变量
private
K
Yar
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
public
K getYar() {
return
Yar
;
}
public
void
setYar(K yar) {
Yar
= yar;
}
public
Point1(T var, K yar) {
this
.
var
= var;
Yar
= yar;
}
}
public
class
PointTest1 {
public
static
void
main(String[] args) {
Point1 point=
new
Point1(20,
"北纬"
);//这里如果不指定泛型,那么系统就会擦除泛型,变为Object类型来接收
/**
警告消息:
Multiple markers at this line
- Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
- Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
- Type safety: The constructor Point1(Object, Object) belongs to the raw type Point1. References to generic type Point1<T,K>
should be parameterized
- Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
- Point1 is a raw type. References to generic type Point1<T,K> should be parameterized
- Type safety: The constructor Point1(Object, Object) belongs to the raw type Point1. References to generic type Point1<T,K>
should be parameterized
*/
//point.setVar(20);
// Point1<String> point1=new Point1<String>();
// point.setYar("北纬");
System.
out
.println(
"x坐标"
+point.getVar());
System.
out
.println(
"y坐标"
+point.getYar());
}
}
结果:
x坐标20
y坐标北纬
5.通配符
class
Info<T>{
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
}
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<String>i=
new
Info<String>();
i.setVar(
"like"
);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info<Object> temp){
System.
out
.println(
"内容"
+temp);
}
}
这样肯定是不行的,如果把代码改为这样:
class
Info<T>{
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
}
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<String>i=
new
Info<String>();
i.setVar(
"like"
);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容like
但是这样有出现安全警告,那到底怎样才好喃?那就是要用泛型的通配符了
定义:表示可以使用任意的泛型对象
代码:
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<String>i=
new
Info<String>();
i.setVar(
"like"
);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info<?> temp){//这里使用了统配符
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容like
6.受限泛型
受限泛型是指在泛型的操作过程中,可以指定一个泛型对象的范围上限和范围下限
格式:
上限:
声明对象: 类名称<? extends 类>对象名称
声明类:访问权限 类名称<泛型标识 extends 类>
下限:
声明对象: 类名称<? super类>对象名称
代码:
声明泛型对象
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<String>i=
new
Info<String>();
i.setVar(
"like"
);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info<?
extends
Number > temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
上面出现错误,是因为,泛型只能接收数字类型
改下代码:
class
Info<T>{
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
}
public
class
TypeTest {
public
static
void
main(String[] args) {
Info< Integer>i=
new
Info< Integer>();
i.setVar(20);
fun(i);
}
public
static
void
fun(Info<?
extends
Number> temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容20
也可以接收其他类型的数字
看代码:
//接收Double
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<Double>i=
new
Info<Double>();
i.setVar(20.28);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info<?
extends
Number> temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容20.28
其他的数字类型就不一一例举了
声明受限泛型类:
代码:
class
Info<T
extends
Number>{//这里声明了受限泛型类
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
}
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<Double>i=
new
Info<Double>();
i.setVar(20.28);
fun(i);
}
public
static
void
fun(Info<?
extends
Number> temp){//这里声明受限泛型方法
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容20.28
泛型下限:
声明受限泛型下限对象:
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<Double>i=
new
Info<Double>();
i.setVar(20.28);
fun(i);
}
public
static
void
fun(Info<?
super
Double> temp){//这里声明泛型下限对象
这里就说明最低接收Double,还可以接收比Double 更高的 Number,Object
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容20.28
代码:
class
Info<T
extends
Double >{//这里声明泛型上限
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
}
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<Double>i=
new
Info<Double>();
i.setVar(20.28);
fun(i);
//这里出现错误,无法传递
}
public
static
void
fun(Info<?
super
Double> temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
结果:
内容20.28
这段代码就是说明 怎样声明上限和下限一起使用
7.泛型与子类继承的限制
一个类的子类可以通过对象多态性来实例化父类对象,但是在泛型中子类无法为为父类实例化对象
代码:
public
class
TypeTest {
public
static
void
main(String[] args) {
Info<Double>i=
new
Info<Double>();
Info<Object>j=
new
Info<Object>();
j= i;
//这里会报错
i.setVar(20.28);
}
public
static
void
fun(Info<?
super
Double> temp){
System.
out
.println(
"内容"
+temp.getVar());
}
}
子类不能实例化父类
8.泛型接口
泛型接口和普通接口也差不多,下面看代码就明白了
interface
Info<T>{
public
T getVar();
}
实现泛型接口有两种方式
interface
Info<T>{
public
T getVar();
}
public
class
TypeTest<T>
implements
Info<T>{
private
T
var
;
public
T getVar() {
return
var
;
}
public
void
setVar(T var) {
this
.
var
= var;
}
public
static
void
main(String[] args) {
TypeTest<String> test=
new
TypeTest<String>();
test.setVar(
"like"
);
System.
out
.println(test.getVar());
}
}
结果:
like
还有一种
interface
Info<T>{
public
T getVar();
}
public
class
TypeTest
implements
Info<String>{
private
String
var
;
public
String getVar() {
return
var
;
}
public
void
setVar(String var) {
this
.
var
= var;
}
public
static
void
main(String[] args) {
TypeTest test=
new
TypeTest();
test.setVar(
"like"
);
System.
out
.println(test.getVar());
}
}
结果:
like
9.泛型数组
public
class
TypeTest {
public
static
void
main(String[] args) {
//Integer i[]={1,2,3,4,5};//静态初始化数组
Integer i[]= fun1(1,2,3,4,5);
fun2(i);
}
public
static
<T> T[] fun1(T...arg){
//可变参数和泛型数组
return
arg;
}
public
static
<T>
void
fun2(T param[]){
for
(T t: param){
System.
out
.print(t+
","
);
}
}
}
结果:
1,2,3,4,5,