java 泛型

一、泛型类的引入

1、问题提出

假设现在有这样的一个需求:需要产生多个对象,每个对象的逻辑完全一样,只是对象内的成员变量的类型不同,那我们如何做。

方法一:
创建多个类文件,给每个类中的成员变量设置指定的数据类型

class Cs1 {
    private int a;

    public Cs1(int a)
    {
        this.a = a;
    }

    public int getData()
    {
        return a;
    }
}

class Cs2 {
    private String a;

    public Cs2(String a)
    {
        this.a = a;
    }

    public String getData()
    {
        return a;
    }
}

public class Test {
    public static void main(String[] args) {
        Cs1 cs1 = new Cs1(12);
        System.out.println(cs1.getData());

        Cs2 cs2 = new Cs2("heavy sea");
        System.out.println(cs2.getData());
    }
}

很显然这种方式会导致类的膨胀,重用性太差

方法二:
由于int和String都继承自Object数据类型,故可以创建一个类文件,给这种类中的成员变量设置Object数据类型。

class Cs1 {
    private Object a;

    public Cs1(Object a)
    {
        this.a = a;
    }

    public Object getData()
    {
        return a;
    }
}


public class Test {
    public static void main(String[] args) {
        Cs1 cs1 = new Cs1(12);
        System.out.println(cs1.getData());

        Cs1 cs2 = new Cs1("heavy sea");
        System.out.println(cs2.getData());
    }
}

但如果对结果类型强制转换,编译的时候正常,运行的时候可能会异常。

除这两种方法外,有没有更好的方法呢?

2、泛型简介:

在JDK 1.5 以后引入,泛型可以在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的。

泛型的原理就是“类型的参数化” 即把类型看做参数,也就是说把所操作的数据类型看作参数,就像方法的形式参数是运行时传递的值的占位符一样。

简单来说,类型变量扮演的角色就如同一个参数,它提供给编译器用来类型检查的信息。

泛型可以提高代码的扩展性和重用性。

泛型类及特点:

1.泛型的类型参数可以是泛型类
2.泛型类可以同时设置多个类型参数
3.泛型类可以继承泛型类
4.泛型类可以实现泛型接口

泛型类应用实例

//	泛型类
class Cs1 <T> {
    private T a;

    public Cs1(T a)
    {
        this.a = a;
    }

    public T getData()
    {
        return a;
    }
}


public class Test {
    public static void main(String[] args) {
        Cs1<Integer> cs1 = new Cs1<Integer>(12);
        System.out.println(cs1.getData());

        Cs1<String> cs2 = new Cs1<String>("heavy sea");
        System.out.println(cs2.getData());
    }
}

/**
 *  泛型类可以继承泛型类
 *  泛型类可以同时设置多个类型参数
 */
class Cs2 <T,T2> extends Cs1 <T> {
    private T2 b;

    public Cs2(T a,T2 b)
    {
        super(a);
        this.b = b;
    }

    public T2 getData2() {
        return b;
    }
}

interface Cs3<T3> {
    abstract void printfData3(T3 a);
}

/**
 *  泛型类可以实现泛型接口
 */
class Cs4<T3> implements Cs3<T3> {
    @Override
    public void printfData3(T3 a) {
        System.out.println("a="+a);
    }
}

二、限制泛型可用类型

1、extends关键字限制泛型可用类型

在定义泛型类别时,默认在实例化泛型类的时候可以使用任何类型,但是如果想要限制使用泛型类型的时候,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口。

class Generic< T extends Animal >{

}

当没有指定泛型继承的类型或接口时,默认使用extends Object,所以默认情况下任何类型都可以作为参数传入。

2、类型通配声明

同一泛型类,如果实例化时给定的实际类型不同,则这些实例的类型是不兼容的,不能互相赋值。
泛型类实例之间的不兼容性会带来使用的不便,我们可以使用泛型通配符(?)声明泛型类的变量就可以解决。

类型通配 例子:
?代表任意一个类型
Generic < Dog > f1 = new Generic< Dog >( );
Generic<?> f = f1;

和限制泛型的上限相似 同样可以使用extends关键字限定通配类型的上限
Generic< Dog > f1 = new Generic< Dog >();
Generic<? extends Animal> f = f1;

还可以使用super关键字将通配符类型限定为某个类型的下限
Generic< Animal > f1 = new Generic< Animal >( );
Generic<? super Dog> f = f1;


class Animal {

}

class Dog extends Animal {

}

class Generic<T>
{
    private T a;

    public Generic(T a) {
        this.a = a;
    }

    public T getA() {
        return a;
    }
}

public class Test2 {
    public static void main(String[] args) {
        Generic<String> g = new Generic<String>("11");
        Generic<Integer> g2 = new Generic<Integer>(12);
        //  g = g2; 实例化类型不同,会报错
        Generic<?> g3 = g;

        //  限制通配符的上限 必须是该类或者该类的子类
        Generic<? extends Animal> g4;
        Generic<Dog> g5 = new Generic<Dog>(new Dog());
        g4 = g5;

        //  限制通配符的下限 必须是该类或者该类的父类
        Generic<? super Dog> g6;
        Generic<Animal> g7 = new Generic<Animal>(new Animal());
        g6 = g7;
    }
}

三、泛型方法:

不仅类可以声明泛型,类中的方法也可以声明仅用于自身的泛型,这种方法叫做泛型方法。
定义格式为:
访问修饰符<泛型列表> 返回类型 方法名{参数} {
}

在泛型列表中声明的泛型,可用于该方法的返回类型声明 参数列表声明 和代码中的局部变量的类型声明

类中的其他方法不能使用当前方法声明的泛型

注意:是否拥有泛型方法,与所在类是否泛型没关系

class Generic<T>{
	T a;
	
	public void printInfo(){
		System.out.println("a="+a);
	}
}

class A {
	
	// 泛型方法
	public <T>void printInfo(T a){
		System.out.println(a);
	}
}

public class Test5 {
	public static void main(String[] args) {
		// 泛型类
		Generic <String>g = new Generic<String>();
		g.printInfo();
		
		// 普通类
		A a1 = new A();
		a1.printInfo("hahaaha");
	}
}

什么时候使用泛型方法,而不是泛型类呢

添加类型约束只作用于一个方法的多个参数之间,而不涉及类中的其他方法
施加类型约束的方法为静态方法,只能将其定义为泛型方法,因为静态方法不能使用其所在类的类型参数。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值