Java学习day13:泛型(一篇文章搞懂)

本文详细介绍了Java中的泛型,包括其原因、使用场景(如ArrayList与集合的区别)、泛型方法、泛型类、抽象类和接口的应用,强调了数据类型一致性的重要性。

声明:该专栏本人重新过一遍java知识点时候的笔记汇总,主要是每天的知识点+题解,算是让自己巩固复习,也希望能给初学的朋友们一点帮助,大佬们不喜勿喷(抱拳了老铁!)


往期回顾:

Java学习day12:static关键字,字符串声明,字符串常量池-优快云博客

Java学习day11:异常-优快云博客

Java学习day10:多态、向下转型、instanceof关键字-优快云博客

......

Java学习day13:泛型

一、泛型

泛型:广泛的类型

1.1为什么要适应泛型

因为在开发中对数据的一致性要求非常高

数组中存的数据  类型都是一致的。
但是数组有一个不好的地方,数组预先定义容量!!!

 public class Demo1 {
public static void main(String[] args) {
        //声明一个int类型数组
        int[] arr = {1, 2, 3, 4};
        char[] chs = {'a', 'b', 'c'};
        //在数组的容量中  数据类型的都是一致的,很好!!!
        //数组中的存储的数据确实一致的,但是开发不用!!!为啥?
        //咱们 使用的时候,容量先定好的,而且数组添加数据删除数据,太麻烦了
   }
}

因此实际开发中使用的是集合

这里我们简单补一下集合的知识点

1.1.1集合ArrayList
1.1.1.1集合和数组的区别
1.数组长度固定,集合长度可变,最开始为1,自动扩容
2.数组能存基本数据类型和引用数据类型,集合能存引用数据类型,如果要存基本数据类型需要用包装类
1.1.1.2集合的增删改查 

ArrayList<String> list=new ArrayList<>();

boolean result=list.add("aaa");//其实是一定可以添加进去的,所以返回值都是true
boolean result=list.remove("aaa");
String str=list.remove(0);

//返回值表示是否修改成功

//删除list集合中索引为0的,返回值就是删除的内容

String str1=list.set(1,"mmm");//修改list集合中索引为1的内容为mmm,返回值就是被覆盖之前的内容
String str2=list.get(2);//长度不再是length而是size方法

 但是我们发现,集合里什么数据类型都可以存,好不好呢?

并不好,我们前面说了,需要保证数据的一致性。

public class Demo1 {
 public static void main(String[] args) {
        //实际开发中咱们需要后面即将学的集合
        //集合就是用来存储的数据的!!!
        ArrayList  list = new ArrayList();//就把他当成一个容器即可
        list.add("狗蛋");
        list.add(250);
        list.add('a');
        list.add(false);
        //啥类型的数据都可以存进来的
        System.out.println(list);
        //以上存储的数据好不好?  一点也不好!!!
        //因为我们对数据类型一致性要求是比较高的!!!
        //现在一个集合里什么数据都有,非常不好
        //取值,每次都需要强转  太不好了
        String str = (String)list.get(0);
        System.out.println(str);
    }
}

因此,基于以上种种,我们引出泛型这一知识点。

import java.util.ArrayList;

public class Demo1 {
    public static void main(String[] args) {
        //可以使用泛型 进行约束
        ArrayList<String> list1 = new ArrayList<>();
        //告知编译器  这个集合只能存String类型的数据
        list1.add("狗蛋");
        list1.add("老邢");
        list1.add("骚磊");
        System.out.println(list1);
        //取值
        String s = list1.get(0);
        System.out.println(s);
       //ArrayList人家底层是封装了好了泛型,人家已经做好的
        //学习自己如何自己写带有泛型的类  泛型的方法 等

    }
}

 1.2带有泛型的方法

1.2.1成员方法和带泛型的语法格式

成员方法:

public 返回值类型  方法名字 (参数列表) {

带泛型:

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

}

这里无意义的占位符: 可以是T   或者E   也可以是?   等  都可以。我们一般用T

1.2.2方法类型
1.2.2.1最初的版本

这个时候其实就是方法的重载

public class Demo2 {
    public static void main(String[] args) {
        test(34);
        test("狗");
        test('蛋');
    }

    public static void test(int a) {
        System.out.println(a);
    }

    public static void test(String a) {
        System.out.println(a);
    }

    public static void test(char a) {
        System.out.println(a);
    }
}

   改进后具有广泛性和普适性,但是其实就是方法的重载的升级版本。

public class Demo2 {
    public static void main(String[] args) {
        test(34);
        test("狗");
        test('蛋');
    }
    //使用泛型的写法
    //这个T只是一个占位而已,如果你传了字符串 那么这个T就是String
    //如果你传了一个整数 那么T  就是Integer
    public static <T> void test (T t) {
        System.out.println(t);
    }
1.2.2.2无参无返回值的方法 
    //无返回值 无参的方法,没有必要使用泛型  没有意义
    public static <T> void test1 () {
        T t = null;
        //你这个结果和泛型有有啥关联?没有任何意义
        System.out.println("嘻嘻哒");
    }
1.2.2.3有参无返回值的方法 
    //无返回值有参数的
    public static <T> void test (T t) {
        System.out.println(t);
    }
1.2.2.4无参有返回值的方法
    //无参 有返回值的方法,有咩有必要使用泛型? 没有
    public static <T> T test2() {
        return null;
    }
1.2.2.5有参有返回值的方法
    //有参 有返回值的方法,这个使用泛型有没有意义? 有!!!
    public static <T> T test3 (T t) {
        return t;
    }

    //总结:
    /**
     * 泛型的方法一定是带有参数的才有意义!!!
     * 无参的都是无意义的,而且一定要注意带有返回值的
     * 这个返回值是和参数的T 数据类型要保持一致的
     */

1.3带有泛型的类 

1.3.1语法格式

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

 //在声明对象的时候,指定好了咱们的T是啥数据类型
 //那么 你的成员变量 T  name 的T就是那种数据类型
但是我们知道,一个类里的成员变量的数据肯定不会是一样的,所以对于成员变量最好是不用,主要是看成员方法

1.3.2注意事项

(1)带有泛型的方法,最起码得有参数

         想要一个方法中的泛型和类保持一致,一定在方法不要加<T>

    public void test1 (T t) {
        System.out.println(t);
    }

  (2)如果在一个带有泛型的类,成员方法加<T> 了,那么此时成员方法的T和类的T是不一样

           此时写的时候最好都不用T,直接用E,跟类的泛型类型区分开

    public <T> void test (T t) {
        System.out.println(t);
    }

(3)如果是静态方法呢?对象创建的时候才 确定E数据类型,静态的方法在创建对象之前

          这个E和上面 类的T无关的  自娱自乐

    public static <E> void test2 (E e) {
        System.out.println(e);
    }

我们把三点注意事项汇总一下:

class Person<T> {

//    T name;//所以成员变量最好不用
//    T age;
//    T sex;
    //主要看成员方法
    //带有泛型的方法,最起码得有参数
    //注意: 如果再一个带有泛型的类,成员方法不要加<T> 了
    public <T> void test (T t) {
        System.out.println(t);
    }
    //想要一个方法中的泛型和类保持一致,一定在方法不要加<T>
    public void test1 (T t) {
        System.out.println(t);
    }
    //如果是静态方法呢?
    //对象创建的时候才 确定E数据类型,静态的方法在创建对象之前
    //这个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  也应该是String
        stringPerson.test(89);
        stringPerson.test1("wuw");
        Person<Integer> person1 = new Person<>();
        //person1.name = 98;
        person1.test1(56);
        //调用静态方法
        Person.test2("hjsj");
    }
}

再次强调:

在泛型类中如果写泛型方法的时候,不需要加<T>
此时方法和类的泛型保持一致,如果加上<T>, 就不再保持一致

1.4带有泛型的抽象类

1.4.1语法格式

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

抽象类,暂时没有办法直接实例化,只能再写一个普通类去继承抽象类
继承了带有泛型的抽象类,那么继承类也需要有泛型!!!

1.4.2示例
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) {
        //是int的包装类  就是代表的是int类型的数据
        TestA<Integer> testA = new TestA<>();
        testA.testA(89);
    }
}

补充介绍

1.4.3八大基本数据类型包装类
int 的包装类Integer
 byte 的包装类 Byte
short 的包装类Short
long 的包装类Long
float 的包装类Float
 double 的包装类  Double
 char  的包装类Character
 boolean 的包装类Boolean

八大基本数据类型的包装类,要熟悉,其实有变化的就是int和char类型,其他都是首字母大写

1.5带有泛型的接口 

1.5.1语法格式

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

 1.5.2案例

//element 元素  Type  类型
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');


    }
}

跟抽象类的继承很像,实现接口,调用实现类的方法

1.6总结

泛型方法:
public <T>  void test (T t) {}
泛型类中的泛型方法,不要这个<T>
public  void test (T t) {}
泛型类:
class Person <T> {

}
抽象类:
abstract class Person<T> {

}
接口:
interface Person<T> {

}

 以上,就是今天的所有知识点了。泛型这个知识点是很简单的,大家静下心慢慢看,慢慢理解,不是什么大问题。

加油吧,预祝大家变得更强!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值