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

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


往期回顾:

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

Java学习day11:异常-CSDN博客

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

......

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 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 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  void test (T t) {
        System.out.println(t);
    }
1.2.2.2无参无返回值的方法 
    //无返回值 无参的方法,没有必要使用泛型  没有意义
    public static  void test1 () {
        T t = null;
        //你这个结果和泛型有有啥关联?没有任何意义
        System.out.println("嘻嘻哒");
    }
1.2.2.3有参无返回值的方法 
    //无返回值有参数的
    public static  void test (T t) {
        System.out.println(t);
    }
1.2.2.4无参有返回值的方法
    //无参 有返回值的方法,有咩有必要使用泛型? 没有
    public static  T test2() {
        return null;
    }
1.2.2.5有参有返回值的方法
    //有参 有返回值的方法,这个使用泛型有没有意义? 有!!!
    public static  T test3 (T t) {
        return t;
    }

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

1.3带有泛型的类 

1.3.1语法格式

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

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

1.3.2注意事项

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

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

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

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

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

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

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

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

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

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

class Person {

//    T name;//所以成员变量最好不用
//    T age;
//    T sex;
    //主要看成员方法
    //带有泛型的方法,最起码得有参数
    //注意: 如果再一个带有泛型的类,成员方法不要加 了
    public  void test (T t) {
        System.out.println(t);
    }
    //想要一个方法中的泛型和类保持一致,一定在方法不要加
    public void test1 (T t) {
        System.out.println(t);
    }
    //如果是静态方法呢?
    //对象创建的时候才 确定E数据类型,静态的方法在创建对象之前
    //这个E和上面 类的T无关的  自娱自乐
    public static  void test2 (E e) {
        System.out.println(e);
    }

}
public class Demo4 {
    public static void main(String[] args) {
        //在声明对象的时候,指定好了咱们的T是啥数据类型
        //那么 你的成员变量 T  name  T 就是那种数据类型
        Person stringPerson = new Person<>();
       // stringPerson.name = "goudan";
        // stringPerson  泛型 是String 就意味着test(T t)
        //T  也应该是String
        stringPerson.test(89);
        stringPerson.test1("wuw");
        Person person1 = new Person<>();
        //person1.name = 98;
        person1.test1(56);
        //调用静态方法
        Person.test2("hjsj");
    }
}

再次强调:

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

1.4带有泛型的抽象类

1.4.1语法格式

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

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

1.4.2示例
abstract class A {
    abstract void testA (T t);
}
class TestA extends A {
    @Override
    void testA(T t) {
        System.out.println(t);
    }
}
public class Demo1 {
    public static void main(String[] args) {
        //是int的包装类  就是代表的是int类型的数据
        TestA 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 {
    //成员方法
    void eat(T t);
}
class TestB implements B {

    @Override
    public void eat(T t) {
        System.out.println(t);
    }
}
public class Demo2 {
    public static void main(String[] args) {
        TestB testB = new TestB<>();
        testB.eat('g');


    }
}

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

1.6总结

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

}
抽象类:
abstract class Person {

}
接口:
interface Person {

}

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

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

 

你可能感兴趣的:(java从0到1,学习,java,intellij-idea,java-ee)