版权声明:本文为博主原创文章,未经博主允许不得转载。多多评论,与博主一起学习编程。 https://blog.csdn.net/Roobert_Chao/article/details/78634340
泛型genericity
泛型就是指类中的属性的类型在实例化对象的时候通过外部进行了指定。
class 类名称<泛型类型,泛型类型,…>{
}
一个泛型的小程序。
package org.study.RobertChao;
public class Info<T>{
private T x;//x属性的类型由外部决定
private T y;//y属性的类型由外部决定
public T getX(){
return x;
}
public void setX(T x){
this.x = x;
}
public T getY(){
return y;
}
public void setY(T y){
this.y = y;
}
}
声明一个具有封装性的类,其中的属性的类型由外部决定,属于泛型。
package org.study.RobertChao;
public class GenDemo00{
public static void main(String[] args){
Info<Integer> i= new Info<Integer>();
i.setX(11);
i.setY(20);
int x = i.getX();//取出x
int y = i.getY();//取出y
System.out.println("x是:"+ x);
System.out.println("y是:"+ y);
}
}
在设置X、Y的参数类型的时候,要求与实例化对象的类型一致。
package org.study.RobertChao;
public class GenDemo01{
public static void main(String[] args){
Info<Integer> i= new Info<Integer>();
i.setX(11);//正确,与<T>的类型要保持一致。
i.setY("二十");//错误,不能设置String类型。
int x =i.getX();//取出x。
int y =i.getY();//取出y。
System.out.println("x是:"+x);
System.out.println("y是:"+y);
}
}
1、在构造方法上引用泛型。
package org.study.RobertChao;
public class Info<T>{
private T x;//x属性的类型由外部决定
private T y;//y属性的类型由外部决定
public Info(T x, T y){
this.setX(x);
this.setY(y);
}//在构造方法中使用泛型,写在参数的构造器中作为参数。
public T getX(){
return x;
}
public void setX(T x){
this.x = x;
}
public T getY(){
return y;
}
public void setY(T y){
this.y = y;
}
}
package org.study.RobertChao;
public class GenDemo02 {
public static void main(String[] args) {
Info<Integer> i= new Info<Integer>(10, 20);
//在调用的时候需要使用构造方法设置内容。
//设置的内容本身依然由泛型指定。
int x = i.getX();//取出x
int y = i.getY();//取出y
System.out.println("x是:"+x);
System.out.println("y是:"+y);
}
}
通过上述的结论可以知道:
类型名称<类型> 变量名称=new 类型名称<类型>(符合构造器的内容)
无参构造器Info<Integer> i=new Info<Integer>();
有参数的构造器Info<Integer> i=new Info<Integer>(10, 20);
2、擦除泛型。
擦出泛型:
使用的时候没有指定泛型的话。
泛型擦除之后,将按照Object进行接收,以保证程序不出现任何的错误。
Infop = new Info(10, 20);
使用泛型的样式是:
Info<Integer> i=new Info<Integer>(10, 20);
3、通配符。
"?"
“?”表示的是可以接收任意的泛型类型。
只是接收输出,并不能修改。
package org.study.RobertChao;
public class GenDemo03{
public static void main(String[] args) {
Info<Object> i1 = new Info<Object>();
Info<Integer> i2 = new Info<Integer>();
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<?> in){
//表示,此时可以接收任意的类型
System.out.println(in.getX());
System.out.println(in.getY());
}
}
泛型上限extends
语法:"? extends 父类"
所包含的最大的内容就是父类的内容。
父类是Number,能够接收到的类型是Number及其子类Integer、etc..
泛型的上限也可以在方法上使用,例如:接受参数。
package org.study.RobertChao;
public class GenDemoup04 {
public static void main(String[] args) {
Info<Integer> in= new Info<Integer>();
fun(in);
}
public static void fun((Point<? extends Number> in)){
//表示,此时可以接收任意的类型
System.out.println(in.getX());
System.out.println(in.getY());
}
}
泛型下限super
语法:"? super 父类"
-
只能设置其具体的类或者父类。
泛型的下限也可以在方法上使用,例如:接受参数。
package org.study.RobertChao;
public class GenDemodown04 {
public static void main(String[] args) {
Info<Integer> in= new Info<Integer>();
fun(in);
}
public static void fun((Point<? super Number>po)){
//表示,此时可以接收任意的类型
System.out.println(in.getX());
System.out.println(in.getY());
}
}
4、泛型接口
公式 interface 接口名称<泛型类型,泛型类型,…>{}
泛型接口的定义:
package org.study.RobertChao;
public interface Demo<T>{//定义泛型接口
public void print(T param);//此抽象方法中使用了泛型类型
}
泛型接口定义完成,后需要定义子类实现此接口。
实现的方法有两种:
The first.
GenDemo05继承了Demo,通过实例化的时候分配的类型决定。
package org.study.RobertChao;
public class GenDemo05<T> implements Demo<T> {
public void print(T param){
System.out.println("param = "+param);
}
}
package org.study.RobertChao;
public class GenDemo06{
public static void main(String[] args) {
Demo<String> demo = new GenDemo05<String>() ;
demo.print("hello") ;
}
}
The Second.
这种方法在类中,一早就输入了合适的类型。
package org.study.RobertChao;
public class GenDemo07 implements Demo<GenDemo07>{
//设置具体类型
public void print(GenDemo07 param){
System.out.println("param = "+param);
}
}
package org.study.RobertChao;
public class GenDemo08{
public static void main(String[] args) {
Demo<GenDemo07> demo = new GenDemo07() ;
demo.print(new GenDemo07()) ;
}
}
5、泛型方法
泛型除了在类中,还可以在方法上使用泛型。
此方法所在的类不一定是泛型的操作类。
package org.study.RobertChao;
public class Demo09{
public <T> T print(T param){//定义泛型方法
//第一个 <T> 表示该方法是泛型方法。
//第二个 T 表示返回值类型是T类型。
return param;
}
}
Demo类中的print()方法里面接收泛型的类型,而且此方法的返回值也是指定的泛型类型。
可以将方法的返回值定义成一个泛型的数组。
package org.study.RobertChao;
public class GenDemo10{
public static void main(String[] args){
Integer i[] = fun(1, 2, 3, 4, 5, 6, 7, 8, 9);
for (int x : i){
System.out.println(x);
}
}
public static <T> T[] fun(T... param){
return param; // 返回数组
}
}
6、泛型嵌套
|- 用一个例子来说明嵌套,(容器里边存放容器)
// 泛型类Info<K,V>
class Info<K,V>{
private K key;
private V value;
// 构造函数
public Info(K key, V val){
this.key = key;
this.value = val;
}
// 设置key
public void setKey(K k){
this.key = k;
}
// 设置value
public void setValue(V v){
this.value = v;
}
// 获取KEY
public K getKey(){
return this.key;
}
// 获取value
public V getValue(){
return this.value;
}
// 覆写toString()方法
public String toString(){
return "Key:"+this.key+", Value:"+this.value;
}
}
// Demo<S>中的S在这代表Info<K,V>,实现泛型嵌套
class Demo<S>{
// 泛型S的对象
private S info;
// Demo构造函数
public Demo(S info) {
this.info = info;
}
// 设置S类型的info
public void setInfo(S info){
this.info = info;
}
// 获取info
public S getInfo(){
return this.info;
}
}
// main
public class GenericEmbeded{
public static void main(String args[]){
// 实例化Info类对象
Info<String,Integer> info = new Info<String, Integer>("石家庄",1);
// 实例化Demo类对象,泛型嵌套
Demo<Info<String,Integer>> d = new Demo< Info<String,Integer>>(info);
// 获取Info<K,V>对象后,再调用toString()方法,最后输出.
System.out.print(d.getInfo());
}
}