java异常 与 泛型<T>
文章目录
- 异常
- 认识异常
- 什么是异常?
- Java的异常体系
- 异常的基本处理
- 异常的作用?
- 自定义异常
- 编译时异常
- 自定义运行时异常
- 异常的处理方案
- 泛型
- 认识泛型
- 泛型类
- 泛型接口
- 泛型方法、通配符、上下限
- 泛型支持的类型
- 包装类
- 包装类具备的其他功能
- 总结
异常
认识异常
什么是异常?
异常代表程序出现的问题
int[] arr = {10, 20, 30};
System.out.println(arr[3]);
// 没有下标为3的元素
System.out.println(10 / 0);
// 除数不能为0
// 读取的文件不存在了
// 读取网络数据,断网了
Java的异常体系
这也是java帮我们写好的我们直接调用就好。
Java.lang.Throwable 这是所有异常的父级
- Error:代表的系统级别错误(属于严重问题),也就是说系统一旦出现问题,sun公司会把这些问题封装成Error对象给出来
( 说白了,Error是给sun公司自己用的,不是给我们程序员用的,因此我们开发人员不用管它) - Exception:叫异常,它代表的才是我们程序可能出现的问题,所以,我们程序员通常会用Exception以及它的孩子来封装程序出现的问题。
- 运行时异常:RuntimeException及其子类,编译阶段不会出现错误提醒,运行时出现的异常(如:数组索引越界异常)
- 编译时异常:编译阶段就会出现错误提醒的。(如:日期解析异常,这里是提示你这里的程序很容易出错。就算你写的是对的也会提示你。)
运行时异常
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo1 {
public static void main(String[] args) {
// 目标:认识异常的体系,搞清楚异常的基本作用。
show();
}
// 定义一个方法认识运行时异常。
public static void show(){
System.out.println("==程序开始。。。。==");
// 运行时异常的特点:编译阶段不报错,运行时出现的异常,继承自 RuntimeException。
int[] arr = {1,2,3};
// System.out.println(arr[3]);
// ArrayIndexOutOfBoundsException 数组越界异常
// System.out.println(10/0);
// ArithmeticException 计算异常
// 空指针异常
String str = null;
System.out.println(str);
System.out.println(str.length());
// NullPointerException 空指针异常。
// 表示程序试图在需要对象的地方使用 null 值进行操作。
System.out.println("==程序结束。。。。==");
}
}
编译时异常: 即使你写的代码是对的也会报错。
下面演示你的代码是正确的但是还会报错的情况。
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo1 {
public static void main(String[] args) {
// 目标:认识异常的体系,搞清楚异常的基本作用。
try {
// 监视代码,出现异常,会被catch拦截住这个异常
show2();
// ==程序开始。。。。==
// Tue Jul 09 11:12:13 CST 2024
// ==程序结束。。。。==
} catch (Exception e) {
e.printStackTrace(); // 打印这个异常信息
}
}
// 定义一个方法认识编译异常。
public static void show2() throws ParseException {
System.out.println("==程序开始。。。。==");
// 编译异常:编译阶段报错,编译不通过。
String str = "2024-07-09 11:12:13";
// 把字符串时间解析成Java中的一个日期对象。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 虽然上面的正确但是我们还是报错加一个throws或者try...catch解决
Date date = sdf.parse(str);
// 这里编译时异常。提醒程序员仔细检查这里。
// 编译时异常,提醒程序员这里的程序很容易出错,请您注意!
// 这就很恶心了明明我们的代码是对的但是还提示异常。这时候就需要使用throws抛出异常
// 说明,你不要管我。我已经知道这里容易出错,
// 但是我已经百分百确定我写的是对的。你直接跑就行了。
System.out.println(date);
System.out.println("==程序结束。。。。==");
}
}
下面演示你的代码是不正确的。但你认为你写对了直接加个throws或者try…catch让程序跑。
import java.io.FileInputStream;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo1 {
public static void main(String[] args) {
try {
// 监视代码,出现异常,会被catch拦截住这个异常
show2();
} catch (Exception e) {
e.printStackTrace(); // 打印这个异常信息
// 提示千万别写错,但是你还是写错了hhhh~~~
// java.text.ParseException
}
}
// 定义一个方法认识编译异常。
public static void show2() throws ParseException {
System.out.println("==程序开始。。。。==");
// 编译异常:编译阶段报错,编译不通过。
String str = "2024-07-09 11:12:13";
// 把字符串时间解析成Java中的一个日期对象。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(str); // 编译时异常,提醒程序员这里的程序很容易出错,请您注意!
System.out.println(date);
System.out.println("==程序结束。。。。==");
}
}
异常的基本处理
两种方式
- 抛出异常(throws)
- 捕获异常(try…catch)
快捷键
Alt+Enter:编译时异常调用 throws或者try…catch
Ctrl+Alt+T : throws / try…catch / if / for …
// 抛出异常(throws)
// 在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
方法 throws 异常1 ,异常2 ,异常3 ..{
…
}
// 捕获异常(try…catch)
//直接捕获程序出现的异常。
...
try{
// 监视可能出现异常的代码!
}catch(异常类型1 变量){
// 处理异常
}catch(异常类型2 变量){
// 处理异常
}
...
实例在上一小节不再过多叙述。
异常的作用?
-
异常是用来定位程序bug的关键信息。
-
可以作为方法内部的一种特殊返回值,以便通知上层调用者,方法的执行问题。
public class ExceptionDemo2 {
public static void main(String[] args) {
// 目标:搞清楚异常的作用。
System.out.println("程序开始执行...");
try {
System.out.println(div(10, 0));
System.out.println("底层方法执行成功了~~~");
} catch (Exception e) {
e.printStackTrace();
System.out.println("底层方法执行失败了~~");
}
System.out.println("程序结束执行...");
// 程序开始执行...
// 除数不能为0,您的参数有问题!
// 底层方法执行失败了~~
// 程序结束执行...
// java.lang.Exception: 除数不能为0,您的参数有问题!
// 下面定位信息
// at com.itheima.demo1exception.ExceptionDemo2.div(ExceptionDemo2.java:28)
// at com.itheima.demo1exception.ExceptionDemo2.main(ExceptionDemo2.java:8)
}
// 需求:求2个数的除的结果,并返回这个结果。
public static int div(int a, int b) throws Exception {
if(b == 0){
System.out.println("除数不能为0,您的参数有问题!");
// 可以返回一个异常给上层调用者,返回的异常还能告知上层底层是执行成功了还是执行失败了!!
throw new Exception("除数不能为0,您的参数有问题!");
}
int result = a / b;
return result;
}
}
自定义异常
Java无法为这个世界上全部的问题都提供异常类来代表, 如果企业自己的某种问题,想通过异常来表示,以便用异常来管理该问题,那就需要自己来定义异常类了。
我们可以使用编译时异常也可以使用运行时异常
编译时异常
/**
* 自定义的运行时异常
* 1、继承RuntimeException做爸爸。
* 2、重写RuntimeException的构造器。
* 3、哪里需要用这个异常返回,哪里就throw
*/
public class ItheimaAgeIllegalRuntimeException extends RuntimeException{
public ItheimaAgeIllegalRuntimeException() {
}
public ItheimaAgeIllegalRuntimeException(String message) {
super(message);
}
}
public class ExceptionDemo3 {
public static void main(String[] args) {
// 目标:认识自定义异常。
System.out.println("程序开始。。。。");
try {
saveAge(300);
System.out.println("成功了!");
} catch (ItheimaAgeIllegalException e) {
e.printStackTrace();
System.out.println("失败了!");
}
System.out.println("程序结束。。。。");
// 程序开始。。。。
// 失败了!
// 程序结束。。。。
// com.itheima.demo1exception.ItheimaAgeIllegalException: 年龄非法 age 不能低于1岁不能高于200岁
// at com.itheima.demo1exception.ExceptionDemo3.saveAge(ExceptionDemo3.java:21)
// at com.itheima.demo1exception.ExceptionDemo3.main(ExceptionDemo3.java:8)
}
// 需求:我们公司的系统只要收到了年龄小于1岁或者大于200岁就是一个年龄非法异常。
public static void saveAge(int age) throws ItheimaAgeIllegalException {
if(age < 1 || age > 200){
// 年龄非法;抛出去一个异常。
throw new ItheimaAgeIllegalException("年龄非法 age 不能低于1岁不能高于200岁");
}else {
System.out.println("年龄合法");
System.out.println("保存年龄:" + age);
}
}
}
自定义运行时异常
- 定义一个异常类继承RuntimeException.
- 重写构造器。
- 通过throw new 异常类(xxx)来创建异常对象并抛出。
特点:编译阶段不报错,运行时才可能出现!提醒不属于激进型。
/**
* 自定义的运行时异常
* 1、继承RuntimeException做爸爸。
* 2、重写RuntimeException的构造器。
* 3、哪里需要用这个异常返回,哪里就throw
*/
public class ItheimaAgeIllegalRuntimeException extends RuntimeException{
public ItheimaAgeIllegalRuntimeException() {
}
public ItheimaAgeIllegalRuntimeException(String message) {
super(message);
}
}
public class ExceptionDemo4 {
public static void main(String[] args) {
// 目标:认识自定义异常-运行时异常
System.out.println("程序开始。。。。");
try {
saveAge(300);
System.out.println("成功了~");
} catch (Exception e) {
e.printStackTrace();
System.out.println("失败了");
}
System.out.println("程序结束。。。。");
// 程序开始。。。。
// 失败了
// 程序结束。。。。
// com.itheima.demo1exception.ItheimaAgeIllegalRuntimeException: 年龄非法 age 不能低于1岁不能高于200岁
// at com.itheima.demo1exception.ExceptionDemo4.saveAge(ExceptionDemo4.java:21)
// at com.itheima.demo1exception.ExceptionDemo4.main(ExceptionDemo4.java:8)
}
// 需求:我们公司的系统只要收到了年龄小于1岁或者大于200岁就是一个年龄非法异常。
public static void saveAge(int age) {
if(age < 1 || age > 200){
// 年龄非法;抛出去一个异常。
throw new ItheimaAgeIllegalRuntimeException("年龄非法 age 不能低于1岁不能高于200岁");
}else {
System.out.println("年龄合法");
System.out.println("保存年龄:" + age);
}
}
}
自定义编译时异常
- 定义一个异常类继承Exception.
- 重写构造器。
- 通过throw new 异常类(xxx) 创建异常对象并抛出。
特点:编译阶段就报错,提醒比较激进
/**
* 自定义的编译时异常
* 1、继承Exception做爸爸。
* 2、重写Exception的构造器。
* 3、哪里需要用这个异常返回,哪里就throw
*/
public class ItheimaAgeIllegalException extends Exception{
public ItheimaAgeIllegalException() {
}
public ItheimaAgeIllegalException(String message) {
super(message);
}
}
public class ExceptionDemo3 {
public static void main(String[] args) {
// 目标:认识自定义异常。
System.out.println("程序开始。。。。");
try {
saveAge(300);
System.out.println("成功了!");
} catch (ItheimaAgeIllegalException e) {
e.printStackTrace();
System.out.println("失败了!");
}
System.out.println("程序结束。。。。");
}
// 需求:我们公司的系统只要收到了年龄小于1岁或者大于200岁就是一个年龄非法异常。
public static void saveAge(int age) throws ItheimaAgeIllegalException {
if(age < 1 || age > 200){
// 年龄非法;抛出去一个异常。
throw new ItheimaAgeIllegalException("年龄非法 age 不能低于1岁不能高于200岁");
}else {
System.out.println("年龄合法");
System.out.println("保存年龄:" + age);
}
}
}
注意:开发时一般使用运行时异常
异常的处理方案
方案1
1、底层异常层层往上抛出,最外层捕获异常,记录下异常信息,并响应适合用户观看的信息进行提示
方案2
2、最外层捕获异常后,尝试重新修复
抛出异常(throws)
在方法上使用throws关键字,可以将方法内部出现的异常抛出去给调用者处理。
方法 throws 异常1 ,异常2 ,异常3 ..{
…
}
// 推荐方式
方法 throws Exception{
}
// Exception代表可以捕获一切异常
捕获异常(try…catch)
直接捕获程序出现的异常。
try{
// 监视可能出现异常的代码!
}catch(异常类型1 变量){
// 处理异常
}catch(异常类型2 变量){
// 处理异常
}...
// 推荐方式
try{
// 可能出现异常的代码!
}catch (Exception e){
e.printStackTrace();
// 直接打印异常对象的信息
}
// Exception代表可以捕获一切异常
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.InputStream;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class ExceptionDemo5 {
public static void main(String[] args) {
// 目标:掌握异常的处理方案1: 底层异常都抛出去给最外层调用者,最外层捕获异常,记录异常,响应合适信息给用户观看。
System.out.println("==程序开始。。。。==");
try {
show();
System.out.println("这次操作成功了~~~");
} catch (Exception e) {
e.printStackTrace();// 捕获异常,记录异常,打印错误给程序员观看。
System.out.println("这次操作失败了~~~");// 捕获异常,记录异常,响应合适信息给用户观看。
}
System.out.println("==程序结束。。。。==");
// ==程序开始。。。。==
// java.text.ParseException: Unparseable date: "2024-07-09 11:12:13"
// at java.base/java.text.DateFormat.parse(DateFormat.java:399)
// at com.itheima.demo1exception.ExceptionDemo5.show(ExceptionDemo5.java:29)
// at com.itheima.demo1exception.ExceptionDemo5.main(ExceptionDemo5.java:15)
// 这次操作失败了~~~
// ==程序结束。。。。==
}
public static void show() throws Exception {
// 编译异常:编译阶段报错,编译不通过。
String str = "2024-07-09 11:12:13";
// 把字符串时间解析成Java中的一个日期对象。
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = sdf.parse(str); // 编译时异常,提醒程序员这里的程序很容易出错,请您注意!
System.out.println(date);
InputStream is = new FileInputStream("D:/meinv.png");
}
}
import java.util.Scanner;
public class ExceptionDemo6 {
public static void main(String[] args) {
// 目标:掌握异常的处理方案2:捕获异常对象,尝试重新修复。
// 接收用户的一个定价
System.out.println("程序开始。。。。");
while (true) {
try {
double price = userInputPrice();
System.out.println("用户成功设置了商品定价:" + price);
break;
} catch (Exception e) {
System.out.println("您输入的数据是瞎搞的,请不要瞎输入价格!");
}
}
// System.out.println("程序结束。。。。");
// 程序开始。。。。
// 请您输入商品定价:
// qw
// 您输入的数据是瞎搞的,请不要瞎输入价格!
// 请您输入商品定价:
// 1
// 用户成功设置了商品定价:1.0
// 程序结束。。。。
}
public static double userInputPrice(){
Scanner sc = new Scanner(System.in);
System.out.println("请您输入商品定价:");
double price = sc.nextDouble();
return price;
}
}
泛型
认识泛型
定义类、接口、方法时,同时声明了一个或者多个类型变量(如:)
称为泛型类、泛型接口,泛型方法、它们统称为泛型。
public class ArrayList<E>{
. . .
}
ArrayList<String> list = new ArrayList<String>();
MyArrayList<String> mlist = new MyArrayList<>(); // JDK 7开始支持的后面类型可以不写
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。
泛型的本质:把具体的数据类型作为参数传给类型变量。
import java.util.ArrayList;
public class GenericDemo1 {
public static void main(String[] args) {
// 目标:认识泛型,搞清楚使用泛型的好处。
// ArrayList<T> list = new ArrayList<T>(); 这可以让程序员自己选择类型。
ArrayList<String> list = new ArrayList<>();
list.add("java");
list.add("php");
// 获取数据。
for (int i = 0; i < list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
}
}
泛型类
类名后面跟
// 修饰符 class 类名<类型变量,类型变量,…> { }
public class ArrayList<E>{ ... }
// 注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
import java.util.ArrayList;
// 自定义泛型类
public class MyArrayList<E> {
private ArrayList list = new ArrayList();
public boolean add(E e){
list.add(e);
return true;
}
public boolean remove(E e){
return list.remove(e);
}
@Override
public String toString() {
return list.toString();
}
}
public class GenericDemo2 {
public static void main(String[] args) {
// 需求:请您模拟ArrayList集合自定义一个集合MyArrayList.
// MyArrayList<String> list = new MyArrayList<String>();
MyArrayList<String> mlist = new MyArrayList<>(); // JDK 7开始支持的后面类型可以不写
mlist.add("hello");
mlist.add("world");
mlist.add("java");
mlist.add("前端");
System.out.println(mlist.remove("world"));// true
System.out.println(mlist);// [hello, java, 前端]
}
}
泛型接口
// 修饰符 interface 接口名<类型变量,类型变量,…> { . .. }
public interface A<E>{ ... }
注意:类型变量建议用大写的英文字母,常用的有:E、T、K、V 等
演示
public class Teacher { }
public class Student { }
package com.itheima.demo3genericity;
// 自定义泛型接口
public interface Data<T> {
void add(T t);
void delete(T t);
void update(T t);
T query(int id);
}
public class StudentData implements Data<Student>{
@Override
public void add(Student student) { }
@Override
public void delete(Student student) { }
@Override
public void update(Student student) { }
@Override
public Student query(int id) {
return new Student();
}
}
public class TeacherData implements Data<Teacher>{
@Override
public void add(Teacher teacher) { }
@Override
public void delete(Teacher teacher) { }
@Override
public void update(Teacher teacher) { }
@Override
public Teacher query(int id) {
return new Teacher();
}
}
public class GenericDemo3 {
public static void main(String[] args) {
// 需求:项目需要对学生数据/老师数据都要进行增删改查操作
StudentData studentData = new StudentData();
studentData.add(new Student());
studentData.delete(new Student());
Student s = studentData.query(1);
}
}
泛型方法、通配符、上下限
// 修饰符 <类型变量,类型变量,…> 返回值类型 方法名(形参列表) { }
// 正确写法
// 修饰符 <泛型> 返回值 方法名
public static <T> void test(T t){ }
// 错误写法
public E get(int index){
return (E) arr[index];
}
// 这才上面的正确写法
public <T> T get(int index) {
return (T) arr[index];
}
public class Student { }
public class GenericDemo4 {
public static void main(String[] args) {
// 需求:打印任意数组的内容。
String[] names = {"赵敏", "张无忌", "周芷若", "小昭"};
printArray(names);
Student[] stus = new Student[3];
printArray(stus);
Student max = getMax(stus);
String max2 = getMax(names);
}
public static <T> void printArray(T[] names){ }
public static <T> T getMax(T[] names){
return null;
}
}
通配符
就是 “?” ,可以在“使用泛型”的时候代表一切类型; E T K V 是在定义泛型的时候使用。
public class Car { }
public class BYD extends Car{ }
public class LX extends Car{ }
public class Xiaomi extends Car{ }
// GenericDemo5.java
import java.util.ArrayList;
public class GenericDemo5 {
public static void main(String[] args) {
// 目标:理解通配符和上下限。
ArrayList<Xiaomi> xiaomis = new ArrayList<>();
xiaomis.add(new Xiaomi());
xiaomis.add(new Xiaomi());
xiaomis.add(new Xiaomi());
go(xiaomis);
ArrayList<BYD> byds = new ArrayList<>();
byds.add(new BYD());
byds.add(new BYD());
byds.add(new BYD());
go(byds);
}
// 需求:开发一个极品飞车的游戏。
// 不能写public static void go(ArrayList<Car> cars)
// 虽然Xiaomi和BYD是Car的子类,但是 ArrayList<Xiaomi> ArrayList<BYD>和 ArrayList<Car> 是没有半毛钱关系!
// 也不能写public static void go(ArrayList<T> cars) 因为T只能在定义的时候使用。
// 所以只能另外开发一个用来使用泛型的符号。于是有了?
public static void go(ArrayList<?> cars) {
}
}
泛型的上下限:
- 泛型上限: ? extends Car: ? 能接收的必须是Car或者其子类 。(常用)
- 泛型下限: ? super Car : ? 能接收的必须是Car或者其父类。
public class Car { }
public class BYD extends Car{ }
public class LX extends Car{ }
public class Xiaomi extends Car{ }
// GenericDemo5.java
import java.util.ArrayList;
public class GenericDemo5 {
public static void main(String[] args) {
// 目标:理解通配符和上下限。
ArrayList<Xiaomi> xiaomis = new ArrayList<>();
xiaomis.add(new Xiaomi());
xiaomis.add(new Xiaomi());
xiaomis.add(new Xiaomi());
go(xiaomis);
ArrayList<BYD> byds = new ArrayList<>();
byds.add(new BYD());
byds.add(new BYD());
byds.add(new BYD());
go(byds);
// ArrayList<Dog> dogs = new ArrayList<>();
// dogs.add(new Dog());
// dogs.add(new Dog());
// dogs.add(new Dog());
// go(dogs);
}
// 需求:开发一个极品飞车的游戏。
// 对于public static void go(ArrayList<?> cars) 来说我们不仅仅可以传进来一只车对象,还可以传进来其他的比如狗这显然不是我们要的。
// 于是发明了给这个?加指定范围。
// 泛型上限: ? extends Car: ? 能接收的必须是Car或者其子类 。这样再来加个狗对象就会报错
public static void go(ArrayList<? extends Car> cars) {
}
}
泛型支持的类型
泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。
基本类型的数据 |
---|
byte |
short |
int |
long |
char |
float |
double |
boolean |
包装类
包装类就是把基本类型的数据包装成对象的类型。
基本数据类型 | 对应的包装类(引用数据类型) |
---|---|
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
为什么要引入包装类
import java.util.ArrayList;
public class GenericDemo6 {
public static void main(String[] args) {
// 目标:搞清楚泛型和集合不支持基本数据类型,只能支持对象类型(引用数据类型)。
ArrayList<int> list = new ArrayList<>();
list.add(12)
// 泛型擦除:泛型工作在编译阶段,等编译后泛型就没用了,所以泛型在编译后都会被擦除。所有类型会恢复成Object类型
// 于是有了 Object o = 12。 但是12并不是一个对象
// 为了实现万物皆对象,于是有了基本数据类型的包装类。
}
}
基本类型的数据包装成对象的方案 |
---|
public Integer(int value):已过时 |
public static Integer valueOf(int i) |
为什么第一种方法过时了。
import java.util.ArrayList;
public class GenericDemo6 {
public static void main(String[] args) {
// 把基本数据类型变成包装类对象。
// 手工包装:
// Integer i = new Integer(100); // 过时
Integer it1 = Integer.valueOf(100); // 推荐的
// 缓存了好多已经封装好的对象,最低的-128最高的127
// valueof方法已经提前在数组里封装好了-128-127的所有对象,这些对象已经new好了。
// 因为-128-127在编程中出现的比较多。他并不希望每次使用都去创建新的对象。
// 创建新的对象占内存
Integer it2 = Integer.valueOf(100); // 推荐的
System.out.println(it1 == it2);// true是同一个地址
Integer it3 = Integer.valueOf(130);
Integer it4 = Integer.valueOf(130);
System.out.println(it3 == it4);// false不是同一个地址
}
}
自动装箱:基本数据类型可以自动转换为包装类型。
自动拆箱:包装类型可以自动转换为基本数据类型。
import java.util.ArrayList;
public class GenericDemo6 {
public static void main(String[] args) {
// 自动装箱成对象:基本数据类型的数据可以直接变成包装对象的数据,不需要额外做任何事情
Integer it11 = 130;
Integer it22 = 130;
System.out.println(it11 == it22);
// 自动拆箱:把包装类型的对象直接给基本类型的数据
int i = it11;
System.out.println(i);
ArrayList<Integer> list = new ArrayList<>();
list.add(130); // 自动装箱
list.add(120); // 自动装箱
int rs = list.get(1); // 自动拆箱
}
}
包装类具备的其他功能
可以把基本类型的数据转换成字符串类型。
public static String toString(double d) |
---|
public String toString() |
可以把字符串类型的数值转换成数值本身对应的真实数据类型。
public static int parseInt(String s) |
---|
public static Integer valueOf(String s) |
import java.util.ArrayList;
public class GenericDemo6 {
public static void main(String[] args) {
// 包装类新增的功能:
// 1、把基本类型的数据转换成字符串。
int j = 23;
String rs1 = Integer.toString(j); // "23"
System.out.println(rs1 + 1); // 231
Integer i2 = j;
String rs2 = i2.toString(); // "23"
System.out.println(rs2 + 1 ); // 231
String rs3 = j + "";
System.out.println(rs3 + 1 ); // 231
System.out.println("-----------------------------------------------------------------------");
// 2、把字符串数值转换成对应的基本数据类型(很有用)。
String str = "98";
// int i1 = Integer.parseInt(str);
int i1 = Integer.valueOf(str);
System.out.println(i1 + 2);
String str2 = "98.8";
// double d = Double.parseDouble(str2);
double d = Double.valueOf(str2);
System.out.println(d + 2);
}
}
总结
为什么要有包装类,包装类有哪些?
- 为了万物皆对象,并且泛型和集合都不支持基本类型,支持包装类
- 8种,int -> Integer , char -> Character,其他的都是首字母大写
包装类提供了哪些常用的功能?
可以把基本类型的数据转换成字符串类型。
public static String toString(double d) |
---|
public String toString() |
可以把字符串类型的数值转换成真实的数据类型。
public static int parseInt(String s) |
---|
public static Integer valueOf(String s) |