Java夯实基础(泛型)

JDK1.5之后出现了新的技术——泛型(Generic),此技术的最大特点是类中的属性的类型可以由外部决定。

而且在声明的时候应该采取如下的形式:

class类名称<泛型类型,泛型类型...>{
}

在使用泛型操作的时候,实际上有很多小的注意点,例如:构造方法上依然可以使用泛型或者有一种称为“泛型的擦除“。

相关术语:
ArrayList《E》:E称为类型变量或类型参数
ArrayList《Integer》:称为参数化类型
ArrayList《Integer》:其中Integer称为类型参数的实例或者实际参数类型
ArrayList《Integer》:<>称为type of

参数化类型与原始数据类型的兼容性
比如:

Collection<String>c=new Vector();
        c.add("string");

或者可以为:

Collection c1=new Vector<String>();
        c1.add("string");

但是注意一点就是,一个子类的对象可以指向一个超类的引用,这是java中的多态。

但是,参数化类型不存在继承关系

比如:

这里写代码片

或者:

Collection<String> c2=new Vector<Object>();

都是错误的!!!

特别注意的就是定义数组不能使用泛型:

比如:

Person<String>[]ps=new Person<String>[];

这是错误的~

两个问题:
1、在构造方法上引用泛型

package com.demo.generic;

public class Person<T> {
    /**
     * 名字
     */
    private String name;
    /**
     * 可能为1岁、一岁、1.5岁(int、string、float)
     */
    private T age;
    public Person(String name, T age) {
        super();
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public T getAge() {
        return age;
    }
    public void setAge(T age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "我叫 :"+name+",我今年"+(age.toString())+"岁";
    }
}

然后我们创建一个Person对象,在构造方法中指定参数类型:

public class Test {
    public static void main(String[] args) {
        Person<String> person =new Person("Yasin", "十八");
        Person<Integer> person2 =new Person<Integer>("Yasin",18);
        Person<Float> person3 =new Person<Float>("Yasin", 17.5f);
        System.out.println(person);
        System.out.println(person2);
        System.out.println(person3);
    }
}

2、如果在使用的时候没有指定泛型的话,则表示擦除泛型,泛型一旦擦除之后,将按照Object进行接收,以保证程序不出现任何的错误。

泛型的擦除为:

//泛型的擦除
        Person person4=new Person("Yasin", 1);

通配符:

“?“表示的是可以接受任意的泛型类型,但是只是接收输出,不能进行修改。

什么意思呢?

比如我们需要打印person对象信息,于是我们定义一个方法:

public static void printInfo(Person<?> p,Object o){
        p.setAge(age);//这里会报错,因为?声明的注解只能输出,不能修改
        System.out.println(p.getAge());
    }

泛型的上线(

public static void printInfo(Person <? extends Number>p,Object o){
        p.setAge(1);
        System.out.println(p.getAge());
    }

这里的p只能传递Number类型或者其子类( Float、Integer…).

泛型的下限

例如:

public static void printInfo(Person <? super Number>p,Object o){
        p.setAge(1);
        System.out.println(p.getAge());
    }

这里的p只能传递Number或者Number的父类…

使用泛型定义接口

如:

package com.demo.generic;

public interface Song<T>{
    void name(T name);
}
class SongImp implements Song<String>{

    @Override
    public void name(String name) {
        // TODO Auto-generated method stub

    }

}

泛型方法

泛型除了定义在类中外,还可以定义在方法上,而且方法上使用泛型,此方法所在的类不一定是泛型的操作类。

例如(定义一个方法,实现任意类型数组两个位置的交换):

public static <T>T[] func(T[]array,int i,int j){
        T temp=array[i];
        array[i]=array[j];
        array[j]=temp;
        return array;
    }

最后就是泛型的嵌套使用

最常见的就是我们的集合框架了:

List<Map<String,String>>datas=new ArrayList<Map<String,String>>();

好啦!!泛型内容就到此结束了额~~~

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值