当前位置: 首页 > article >正文

JAVA中包装类和泛型 通配符

目录

1. 包装类

1.1 基本数据类型和对应的包装类

1.2 装箱和封箱

1.3 自动自动装箱和封箱

2. 什么是泛型

3. 引出泛型

3.1 语法

4. 泛型类的使⽤

4.1 语法

4.2 ⽰例

4.3 类型推导(Type Inference)

5 泛型的上界

5.1 语法

6. 通配符

6.1 通配符解决什么问题

6.2 通配符上界

6.3 通配符下界


1. 包装类

在Java中,由于基本类型不是继承⾃Object,为了在泛型代码中可以⽀持基本类型,Java给每个基本类型都对应了⼀个包装类型。

1.1 基本数据类型和对应的包装类

出了Integer和Characterr,其余基本类型的包装类都是⾸字⺟⼤写。

1.2 装箱和封箱

虽然包装类,确实是类。在使用的时候,进行算数运算的时候,还需要转换成内置类型进行计算。

包装类和内置类型转换

内置类型     ————》   包装类        装箱

包装类        ————》   内置类型     拆箱

1.3 自动自动装箱和封箱

从JAVA8开始就可以实现自动装箱和拆箱。

public class Test1 {
    public static void main(String[] args) {
        //内置类型,复制给包装类,自动装箱
        Integer a = 10;
        //包装类,赋值给内置类型,自动拆箱
        int b = a;
    }
}

进行算数运算

public class Test1 {
    public static void main(String[] args) {
//        //内置类型,复制给包装类,自动装箱
//        Integer a = 10;
//        //包装类,赋值给内置类型,自动拆箱
//        int b = a;
        Integer a = 10;
        Integer b = 20;
        System.out.println(a+b);
    }
}

这里的a+b是针对两个Integr先进行转换成int,在进行计算。自动拆箱(其实就是隐士类型转换)。

对于包装类来说直接拿过来用即可。当作内置类型。不过有些地方只能用包装类,不能用内置类型。

2. 什么是泛型

⼀般的类和⽅法,只能使⽤具体的类型: 要么是基本类型,要么是⾃定义的类。如果要编写可以应⽤于多种类型的代码,这种刻板的限制对代码的束缚就会很⼤
                                                                      ----- 来源《Java编程思想》对泛型的介绍。
泛型是在JDK1.5引⼊的新的语法,通俗讲泛型:就是适⽤于许多许多类型。从代码上讲,就是对类型实现了参数化。

3. 引出泛型

实现⼀个类,类中包含⼀个数组成员,使得数组中可以存放任何类型的数据,也可以根据成员⽅法返回数组中某个下标的值
1. 我们以前学过的数组,只能存放指定类型的元素。
例如:
int[] array = new int[10];
String[] strs = new String[10];

3.1 语法

基础写法:
class 泛型类名称<类型形参列表> {
// 这⾥可以使⽤类型参数

   }
class ClassName<T1, T2, ..., Tn> {
 }

其他写法:

class 泛型类名称<类型形参列表> extends 继承类/* 这⾥可以使⽤类型参数 */ {
// 这⾥可以使⽤类型参数
}
class ClassName<T1, T2, ..., Tn> extends ParentClass<T1> {
// 可以只使⽤部分类型参数
}

4. 泛型类的使⽤

4.1 语法

泛型类<类型实参> 变量名; // 定义⼀个泛型类引⽤
new 泛型类<类型实参>(构造⽅法实参); // 实例化⼀个泛型类对象

4.2 ⽰例

MyArray<Integer> list = new MyArray<Integer>();
注意:泛型只能接受类,所有的基本数据类型必须使⽤包装类!
//<T>就是“参数类型”
//T就是一个类型,相当于是:“形参”
class ArrayTemplate<T> {
    //此时arr是T[]类型,T是类型?还不知道,得在后边实例化的时候才能知道。
    //由于T类型未知,不能直接new T[]    类型转换
    private T[]arr = (T[]) new Object[10];
    public T get(int index){

        return arr[index];
    }
    public void set (int index ,T value){
        arr[index] = value;
    }


}
public class Test2 {
    //针对上述ArrayTemplate进行实例化
    //反省参数类型T就指定为Integer
    //针对arr1来说,只能储存Integer类型的数据
    ArrayTemplate<Integer> arr1 = new ArrayTemplate<Integer>();

    //泛型参数类型 T 就指定为String
    //针对Arr2 来说,就只能存储 String 类型的数据
    ArrayTemplate<String> arr2 = new ArrayTemplate<String>();

    //针对arr3来说,就只能存储Book类型
    ArrayTemplate<Book> arr3 = new ArrayTemplate<Book>();

}

针对泛型参数来说,只能指定引用类型,不能指定内置类型。

4.3 类型推导(Type Inference)

当编译器可以根据上下⽂推导出类型实参时,可以省略类型实参的填写
MyArray<Integer> list = new MyArray<>(); // 可以推导出实例化需要的类型实参为Integer
⼩结:
1. 泛型是将数据类型参数化,进⾏传递
2. 使⽤ <T> 表⽰当前类是⼀个泛型类。
3. 泛型⽬前为⽌的优点:数据类型参数化,编译时⾃动进⾏类型检查和转换

泛型的上界

在定义泛型类时,有时需要对传⼊的类型变量做⼀定的约束,可以通过类型边界来约束。

5.1 语法

class 泛型类名称<类型形参 extends 类型边界> {
...
}

实例:

public class MyArray<T extends Number> {
     ...
}

 只接受 Number 的⼦类型作为 T 的类型实参

​

public class Test3 <T extends Number>{
    public static void main(String[] args) {
        Test3<Integer> t1 = new Test3<>();
        Test3<Double> t2 = new Test3<>();
        Test3<Float> t3 = new Test3<>();

        //String类型不是Number的子类
        // Test3<String> t4 = new Test3<>();

    }

}

​

6. 通配符

? ⽤于在泛型的使⽤,即为通配符

6.1 通配符解决什么问题

在"?"的基础上⼜产⽣了两个⼦通配符:
? extends 类:设置通配符上限
? super 类:设置通配符下限

6.2 通配符上界

语法:
<? extends 上界>
<? extends Number>//可以传⼊的实参类型是Number或者Number的⼦类
public class Test4 <T> {
    public static void main(String[] args) {
//        Test4<Integer> t = new Test4<>();
//
//        t = new Test4<String>();

        //这个情况,T来说,无论是啥参数类型 ,都可以通过t来指向
        //此处 ? 称为通配符。
//        Test4<?> t = new Test4<>();
//
//        t = new Test4<String>();


        //指定了通配符的上界
        //此时的t 可以指向泛型参数为Number 及其子类的情况

        Test4<? extends Number> t = new Test4<>();
        t = new Test4<Double>();

//       错误写法,String不是NUmber的子类
        t = new Test4<String>();
   }
}

6.3 通配符下界

语法

<? super 下界>
<? super Integer>//代表 可以传⼊的实参的类型是Integer或者Integer的⽗类类型



http://www.kler.cn/a/561589.html

相关文章:

  • 【EB-05】TC397 Tresos 配置Dio模块
  • K8s部署主从结构MySQL服务
  • 在Linux桌面上创建Idea启动快捷方式
  • 在安装IRkernel时一直在解决环境
  • Https解决了Http的哪些问题
  • 给Python加入自己的函数
  • QT线程同步
  • 团体程序设计天梯赛-练习集——L1-051 打折
  • 从零开始:OpenCV计算机视觉基础教程【图像基本操作】
  • 量子计算在金融风险评估中的应用:革新与突破
  • [实现Rpc] 测试 | rpc部分功能联调 | debug | 理解bind
  • 【大模型】Ubuntu下 fastgpt 的部署和使用
  • kafka队列堆积的常见解决
  • Linux设备驱动开发-UART驱动
  • Docker打包Python项目
  • 全价值链数字化转型:以美的集团为例,探索开源AI大模型与S2B2C商城小程序源码的融合应用
  • C++ 多态小练习
  • 短视频矩阵系统源码开发/矩阵系统OEM搭建
  • 贪心算法:JAVA从理论到实践的探索
  • Centos主机基础设置和网络网卡设置,安装ansible、docker(修改ip、uuid、主机名、关闭防火墙selinux和networkmanager)