Java基础之泛型

1.为什么要使用泛型

泛型意为广泛的类型。
在实际应用中,人们对数据的一致性要求比较看重!如数组之类,每次数据类型都是预先设定好的,但其容量有限,且修改起来较为麻烦。集合则可以存储不同类型数据,存储容量可自动扩容,但每次取值都需要强转。使用集合,同时借助于泛型则可以统一集合中存储数据的类型,且存储容量可自动扩容。

代码示例1:

import java.util.ArrayList;

public class Demo2 {
    public static void main(String[] args) {
        //声明一个集合
        //可以看作一个容器
        ArrayList list = new ArrayList();
        //向集合中添加元素
        //可以添加不同类型的元素(多态,形参为object),且数量没有限制
        list.add("念奴");
        list.add('娇');
        list.add(true);
        System.out.println(list); //[念奴, 娇, true]

        //取值,借助于get(int index)方法
        //需要强转
        String str = (String)list.get(0);
        System.out.println(str); //念奴

        //借助泛型,可以对存储数据的类型进行约束
        //告知编译器,只能存储String类型的数据
        ArrayList<String> list1 = new ArrayList<>();
        list1.add("如花");
        list1.add("似玉");
        System.out.println(list1); //[如花, 似玉]
        //取值
        String str1 = list1.get(0);
        System.out.println(str1); //如花
    }
}

2.带有泛型的方法

语法格式:

public <无意义的占位符> 返回值类型 方法名字(参数列表) {

}

//无意义的占位符:可以是T E ?等。
//静态方法要在public后加static。

代码示例2:

public class Demo3 {
    public static void main(String[] args) {
        test3("如花");
        test3('似'); 
        System.out.println(test4(81.88));
        System.out.println(test4(true));
        //传入不同类型的数据均不会报错
        //T仅作为一个占位,体现了泛型的广泛性和普适性
    }
    //使用泛型的静态方法
    //无参无返回值  (使用泛型并无意义)
    public static <T> void test1() {
        System.out.println("呵呵");
    }
    //无参有返回值  (使用泛型并无意义)
    public static <T> T test2() {
        return null; //返回值为T时,只能返回null
    }
    //有参无返回值
    public static <T> void test3(T t) {
        System.out.println(t);
    }
    //有参有返回值
    public static <T> T test4(T t) {
        return t;
    }

//    //有参有返回值,参数为多个
//    //因为不能保证传入的参数类型一致,所以会编译出错
//    public static <T> T test5(T t1, T t2) {
//        return t1 + t2;
//    }
}

代码示例3:

class Dog {
	//使用泛型的成员方法
    public <T> void test (T t) {
        System.out.println(t);
    }
}
public class Demo3 {
    public static void main(String[] args) {
        Dog dog = new Dog();
        //传入不同类型的数据均不会报错
        dog.test("goudan");
        dog.test(89);
        dog.test(90.8);
    }
}

总结:

1.并不是所有方法都适合用泛型来写。一定是带有参数的泛型方法才有意义。

2.泛型方法的返回值要与参数类型保持一致。

3.带有泛型的类

语法格式:

class 类名<无意义的占位符> {

}

代码示例4:

class Person<T> {

//    T name;
//    T age;
//    T sex;
    //属性统一用一种数据类型并不合理,因此一般成员变量不用泛型

    //带有泛型的成员方法(有参)
    //如果成员方法中加了<T>,那么参数中的T类型与声明处的T类型无关
    public <T> void test (T t) {
        System.out.println(t);
    }
    //想要一个方法中的泛型和类保持一致,一定不要在方法中加<T>
    public void test1 (T t) {
        System.out.println(t);
    }
    //静态的方法在创建对象之前,因此静态方法中的E和类声明处的T无关的
    public static <E> void test2 (E e) {
        System.out.println(e);
    }
}
public class Demo4 {
    public static void main(String[] args) {
        //在声明对象的时候,指定好T是什么数据类型,那么成员变量T name中的T就是那种数据类型
        Person<String> stringPerson = new Person<>();
       // stringPerson.name = "goudan";
        // stringPerson  泛型 是String 就意味着test(T t)
        //创建对象时规定的T的类型不影响test(T t)中参数的类型
        stringPerson.test(89);
        //但会影响test1(T t)中参数的类型
        stringPerson.test1("wuw");
        
        Person<Integer> person1 = new Person<>();
        //person1.name = 98;
        person1.test1(56);
        //调用静态方法
        Person.test2("hjsj");
    }
}

总结:

1.在一个带有泛型的类中,对于成员方法就不要再加了,如此成员方法中的T与类声明处的的类型才是一致的。

2.在一个带有泛型的类中,如果要写带有泛型的静态成员方法,需要加无意义的占位符,此处E的类型与类声明处的T的类型无关。

4.带有泛型的抽象类

语法格式:

abstract class 类名<无意义的占位符> {

}

代码示例5:

abstract class A<T> {
    abstract void testA (T t);
}
class TestA<T> extends A<T> {

    @Override
    void testA(T t) {
        System.out.println(t);
    }
}
public class Demo1 {
    public static void main(String[] args) {
        //Integer是int的包装类  就是代表的是int类型的数据
        TestA<Integer> testA = new TestA<>();
        testA.testA(89);
    }
}

5.带有泛型的接口

语法格式:

interface 接口名字<无意义的占位符> {

}

代码示例6:

interface B<T> {
    //成员方法
    void eat(T t);
}
class TestB<T> implements B<T> {

    @Override
    public void eat(T t) {
        System.out.println(t);
    }
}
public class Demo2 {
    public static void main(String[] args) {
        TestB<Character> testB = new TestB<>();
        testB.eat('g');
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值