Java基础14(Enum 枚举类 BigInteger类BigDecimal类 内部类)

2024-05-23 22:04

本文主要是介绍Java基础14(Enum 枚举类 BigInteger类BigDecimal类 内部类),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

目录

一. Enum 枚举类

1. enum的定义

2. enum的比较:

3. enum类型

4. enum方法

4.1 name()方法

4.2 ordinal()方法

4.3 toString()方法

5. switch 

6. 小结

二. BigInteger类 

三. BigDecimal类 

1. 一些方法

1.1 scale()方法

1.2 stripTrailingZeros()方法

1.3 setScale()方法

1.4 一些运算

1.5 divideAndRemainder()方法

2. 比较BigDecimal

四. Random类和SecureRandom类

1. Random类

2. SecureRandom类

五. 内部类

1. Inner Class 内部类

2. Anonymous Class 匿名类

3. Static Nested Class静态内部类


一. Enum 枚举类

1. enum的定义

为了让编译器能自动检查某个值在枚举的集合内,并且,不同用途的枚举需要不同的类型来标记,不能混用,我们可以使用enum来定义枚举类

枚举类Weekday :

public enum Weekday {SUN, MON, TUE, WED, THU, FRI, SAT;
}

枚举类Color:

public enum Color {RED, GREEN, BLUE;
}

测试类:

public static void main(String[] args) {//设置枚举值://编译器帮助我们进行数据类型的校验,以及取值范围的校验Weekday day = Weekday.SUN;if (day == Weekday.SAT || day == Weekday.SUN) {System.out.println("休息");} else {System.out.println("学习");}}

枚举和int定义的常量相比,使用enum定义枚举有如下好处:
●enum常量本身带有类型信息,即Weekday.SUN类型是Weekday,编译器会自动检查出类型错误例如,下面的语句不可能编译通过:

int day = 1;// Compile error: bad operand types for binary operator '=='
if (day == Weekday.SUN) {}

●不可能引用到非枚举的值,因为无法通过编译。
●不同类型的枚举不能互相比较或者赋值,因为类型不符。
例如,不能给一个Weekday枚举类型的变量赋值为Color枚举类型的值:

Weekday x = Weekday.SUN; // ok!
Weekday y = Color.RED; // Compile error: incompatible types

2. enum的比较:

引用类型比较,要使用equals()方法,如果使用==比较,它比较的是两个引用类型的变量是否是同一个对象。因此,引用类型比较,要始终使用equals()方法,但enum类型可以例外。

因为enum类型的每个常量在JVM中只有一个唯一实例,所以可以直接用比较:

Weekday day = Weekday.SUN;if (day == Weekday.SAT || day == Weekday.SUN) {System.out.println("休息");}

3. enum类型

enum定义的类型就是class,只不过它有以下几个特点:
●定义的enum类型总是继承自java.lang.Enum,且无法被子类继承;
●只能定义出enum的实例,而无法通过new操作符创建enum的实例;
●定义的每个实例都是引用类型的唯一实例;
●可以将enum类型用于switch语句。

Color枚举类:

public enum Color {RED(1, "红色"), BLUE(2, "蓝色"), GREEN(3, "绿色");private final int value;private final String name;private Color(int value, String name) {this.value = value;this.name = name;}@Overridepublic String toString() {return value + name;}public int getValue() {return value;}public String getName() {return name;}}

Color01类:

public final class Color01  { // extends Enum// 每个实例均为全局唯一:public static final Color01 RED = new Color01(1,"红色");public static final Color01 BLUE = new Color01(2,"蓝色");public static final Color01 GREEN = new Color01(3,"绿色");public final int value;public final String name;// private构造方法,确保外部无法调用new操作符:private Color01(int value, String name) {super();this.value = value;this.name = name;}
}

编译后的enum类和普通class并没有任何区别。但是我们自己无法按定义普通class那样来定义enum,必须使用enum关键字,这是Java语法规定的。

4. enum方法

由于enum是一个class,每个枚举的值都是class实例,因此,这些实例有一些方法:

4.1 name()方法

作用:返回常量名

//name()作用:返回常量名String colorName = Color.BLUE.name();System.out.println(colorName);//BLUE

4.2 ordinal()方法

作用:返回定义的常量的顺序,从0开始计数

//ordinal()作用:返回定义的常量的顺序,从0开始计数int i = Color.BLUE.ordinal();System.out.println(i);//1

因为enum本身是class,所以我们可以定义private的构造方法,并且,给每个枚举常量添加字段,这样就无需担心顺序的变化,新增枚举常量时,也需要指定一个int值.

public enum Color {RED(1, "红色"), BLUE(2, "蓝色"), GREEN(3, "绿色");private final int value;private final String name;private Color(int value, String name) {this.value = value;this.name = name;}
@Overridepublic String toString() {return value + name;}
}

注意:枚举类的字段也可以是非final类型,即可以在运行期修改,但是不推荐这样做!

4.3 toString()方法

作用:默认情况下,对枚举常量调用toString()会返回和name()一样的字符串。但是,toString()可以被覆写,而name()则不行。

//toString()默认情况下,会返回和name()一样的字符串,但是此方法没有重写,我们可以手动进行重写String str1 = Color.BLUE.toString();System.out.println(str1);//2蓝色
public enum Color {RED(1, "红色"), BLUE(2, "蓝色"), GREEN(3, "绿色");private final int value;private final String name;private Color(int value, String name) {this.value = value;this.name = name;}@Overridepublic String toString() {return value + name;}
}

5. switch 

枚举类可以应用在switch语句中。因为枚举类天生具有类型信息和有限个枚举常量,所以比int、String类型更适合用在switch语句中:

public static void main(String[] args) {Color c = Color.BLUE;switch (c) {case BLUE:System.out.println("蓝色");break;case RED:System.out.println("红色");break;case GREEN:System.out.println("绿色");break;default:break;}
}

注意:加上default语句,可以在漏写某个枚举常量时自动报错,从而及时发现错误。

6. 小结

●Java使用enum定义枚举类型,它被编译器编译为final class Xxx extends Enum { … }
●通过name()获取常量定义的字符串,注意不要使用toString()
●通过ordinal()返回常量定义的顺序(无实质意义)
●可以为enum编写构造方法、字段和方法
●enum的构造方法要声明为private,字段强烈建议声明为final
●enum适合用在switch语句中

二. BigInteger类 

java.math.BigInteger就是用来表示任意大小的整数。BigInteger内部用一个int[]数组来模拟一个非常大的整数:

BigInteger bi = new BigInteger("1234567890");// 2867971860299718107233761438093672048294900000
System.out.println(bi.pow(5)); 

对做运算的时候,只能使用实例方法:

        BigInteger bg1 = new BigInteger("100");BigInteger bg2 = new BigInteger("3");System.out.println(bg1.add(bg2));//加 103System.out.println(bg1.subtract(bg2));//减 97System.out.println(bg1.multiply(bg2));//乘 300System.out.println(bg1.divide(bg2));//除 33System.out.println(bg1.pow(3));//幂 1000000

 BigInteger和Integer、Long一样,也是不可变类,并且也继承自Number类。因为Number定义了转换为基本类型的几个方法:
○转换为byte:byteValue()
○转换为short:shortValue()
○转换为int:intValue()
○转换为long:longValue()
○转换为float:floatValue()
○转换为double:doubleValue()
因此,通过上述方法,可以把BigInteger转换成基本类型。如果BigInteger表示的范围超过了基本类型的范围,转换时将丢失高位信息,即结果不一定是准确的。如果需要准确地转换成基本类型,可以使用intValueExact()、longValueExact()等方法,在转换时如果超出范围,将直接抛出ArithmeticException异常。

BigInteger i = new BigInteger("123456789000");
System.out.println(i.longValue()); // 123456789000
System.out.println(i.multiply(i).longValueExact()); // java.lang.ArithmeticException: BigInteger out of long range

注意:使用longValueExact()方法时,如果超出了long型的范围,会抛出ArithmeticException。

三. BigDecimal类 

BigDecimal和BigInteger类似,BigDecimal可以表示一个任意大小且精度完全准确的浮点数。

        double d1 = 0.1;double d2 = 0.2;System.out.println(d1+d2);//0.30000000000000004BigDecimal b1 = new BigDecimal(0.1);BigDecimal b2 = new BigDecimal(0.2);System.out.println(b1.add(b2));//0.3000000000000000166533453693773481063544750213623046875//使用BigDecima1时候一定要注意,构造方法要为String类型BigDecimal a = new BigDecimal("0.1");BigDecimal b = new BigDecimal("0.2");System.out.println(a.add(b));//0.3

1. 一些方法

1.1 scale()方法

BigDecimal用scale()表示小数位数:

BigDecimal b1 = new BigDecimal("123.45");BigDecimal b2 = new BigDecimal("123.4500");BigDecimal b3 = new BigDecimal("1234500");//获取BigDecimal类型的小数位数,方法scale()System.out.println(b1.scale());//2System.out.println(b2.scale());//4System.out.println(b3.scale());//0

1.2 stripTrailingZeros()方法

通过BigDecimal的stripTrailingZeros()方法,可以将一个BigDecimal格式化为一个相等的,但去掉了末尾0的BigDecimal:

BigDecimal b1 = new BigDecimal("123.45");BigDecimal b2 = new BigDecimal("123.4500");BigDecimal b3 = new BigDecimal("1234500");//stripTrailingzeros()方法,可以将一个BigDecimal格式化为一个相等的,但去掉了末尾0的BigDecimal:System.out.println(b1.stripTrailingZeros().scale());//2System.out.println(b2.stripTrailingZeros().scale());//2System.out.println(b3.stripTrailingZeros().scale());//-2

如果一个BigDecimal的scale()返回负数,例如,-2,表示这个数是个整数,并且末尾有2个0。

1.3 setScale()方法

可以对一个BigDecimal设置它的scale,如果精度比原始值低,那么按照指定的方法进行四舍五入或者直接截断:

●四舍五入:

BigDecimal bg1 = new BigDecimal("123.45");// 四舍五入BigDecimal bigDecimal1 = bg1.setScale(1, RoundingMode.HALF_UP);System.out.println(bigDecimal1);// 123.5

●直接截断:

// 直接截断BigDecimal bg2 = new BigDecimal("123.44");BigDecimal bigDecimal2 = bg2.setScale(1, RoundingMode.DOWN);System.out.println(bigDecimal2);// 123.4

1.4 一些运算

BigDecimal bg1 = new BigDecimal("1");BigDecimal bg2 =new BigDecimal("0.3");System.out.println(bg1.add(bg2));//加 1.3System.out.println(bg2.subtract(bg1));//减 -0.7System.out.println(bg1.multiply(bg2));//乘 0.3//除法运算的时候,除不尽,在进行除法运算的时候推荐使用三参的divide,保留结果的位数,//System.out.println(bg1.divide(bg2));// 报错:ArithmeticException,因为除不尽System.out.println(bg1.divide(bg2,3,RoundingMode.HALF_UP));//3.333

1.5 divideAndRemainder()方法

调用divideAndRemainder()方法时,返回的数组包含两个BigDecimal,分别是商和余数,其中商总是整数,余数不会大于除数。我们可以利用这个方法判断两个BigDecimal是否是整数倍数:

BigDecimal bg1 = new BigDecimal("1");BigDecimal bg2 = new BigDecimal("0.2");// divideAndRemainder()返回的数组包含两个BigDecimal,第一个元素是商,第二个元素是余BigDecimal[] result = bg1.divideAndRemainder(bg2);System.out.println(Arrays.toString(result));//[5, 0.0]if (result[1].doubleValue() == 0.0) {System.out.println("可以除尽");}System.out.println("===============");System.out.println(new BigDecimal("0.00000000").signum());System.out.println("===============");//	signum>0 返回1
//		  =0     0
//          <0 返回-1if (result[1].signum() == 0) {System.out.println("可以除尽");}

2. 比较BigDecimal

在比较两个BigDecimal的值是否相等时,要特别注意,使用equals()方法不但要求两个BigDecimal的值相等,还要求它们的scale()相等:

        BigDecimal bg1 = new BigDecimal("12.35");BigDecimal bg2 = new BigDecimal("12.3500");System.out.println("地址是否相同:" + (bg1 == bg2));//false// 内容比较精准度一样bg1=bg1.stripTrailingZeros();bg2=bg2.stripTrailingZeros();System.out.println("内容比较"+bg1.equals(bg2));//true

必须使用compareTo()方法来比较,它根据两个值的大小分别返回负数、正数和0,分别表示小于、大于和等于。

//	>0 第一个比第二个大
//	=0 相等
//	<0 第一个小于第二个BigDecimal bg1 = new BigDecimal("12.35");BigDecimal bg2 = new BigDecimal("12.3500");int result = bg1.compareTo(bg2);System.out.println("内容相等比较:" + (result == 0));//true

 ●BigDecimal用于表示精确的小数,常用于财务计算
● 比较BigDecimal的值是否相等,必须使用compareTo()而不能使用equals()

四. Random类和SecureRandom类

Java的核心库提供了大量的现成的类供我们在开发编程时使用。

1. Random类

Random用来创建伪随机数。所谓伪随机数,是指只要给定一个初始的种子,产生的随机数序列是完全一样的。要生成一个随机数,可以使用nextInt()、nextLong()、nextFloat()、nextDouble():

//产生随机序列的随机数对象Random random = new Random();System.out.println(random.nextInt());//每次都不一样System.out.println(random.nextInt(10));//生成一个[0,10)之间的intSystem.out.println(random.nextDouble());//生成一个[0,1)之间的doubleSystem.out.println(random.nextLong());//每次都不一样//使用随机数填充字节数组byte[] bytes = new byte[10];random.nextBytes(bytes);System.out.println(Arrays.toString(bytes));

 因为我们创建Random实例时,如果不给定种子,就使用系统当前时间戳作为种子,因此每次运行时,种子不同,得到的伪随机数序列就不同。如果我们在创建Random实例时指定一个种子,就会得到完全确定的随机数序列:

// 随机数种子相同,随机序列完全相同Random r1 = new Random(10);Random r2 = new Random(10);for (int i = 0; i < 10; i++) {System.out.print(r1.nextInt(100) + " ");}System.out.println();for (int i = 0; i < 10; i++) {System.out.print(r2.nextInt(100) + " ");}

Math.random()实际上内部调用了Random类,所以它也是伪随机数,只是我们无法指定种子

2. SecureRandom类

SecureRandom就是用来创建安全的随机数的:

SecureRandom无法指定种子,它使用RNG(random number generator)算法。JDK的SecureRandom实际上有多种不同的底层实现,有的使用安全随机种子加上伪随机数算法来产生安全的随机数,有的使用真正的随机数生成器。实际使用的时候,可以优先获取高强度的安全随机数生成器,如果没有提供,再使用普通等级的安全随机数生成器:

// 获取普通的安全随机数生成器SecureRandom sc = new SecureRandom();System.out.println(sc.nextInt());System.out.println(sc.nextInt(10));System.out.println(sc.nextDouble());// 获取高强度安全随机数生成器SecureRandom sc1 = SecureRandom.getInstanceStrong();System.out.println(sc1.nextInt());System.out.println(sc1.nextInt(10));System.out.println(sc1.nextDouble());//随机数填充字节数组byte[] bytes = new byte[10];sc1.nextBytes(bytes);System.out.println(Arrays.toString(bytes));
SecureRandom sc = null;try {// 获取高强度安全随机数生成器sc=SecureRandom.getInstanceStrong();} catch (NoSuchAlgorithmException e) {// 获取普通的安全随机数生成器sc = new SecureRandom();}System.out.println(sc.nextInt());// 用安全随机数填充bytesbyte[] bytes =new byte[10];sc.nextBytes(bytes);System.out.println(Arrays.toString(bytes));

SecureRandom的安全性是通过操作系统提供的安全的随机种子来生成随机数。时刻牢记必须使用SecureRandom来产生安全的随机数。

注意:需要使用安全随机数的时候,必须使用SecureRandom,绝不能使用Random!

五. 内部类

1. Inner Class 内部类

语法规则:

class Outer {class Inner {// 定义了一个Inner Class}
}

Outer是一个普通类,而Inner是一个Inner Class,它与普通类最大的区别:Inner Class的对象实例不能单独存在,必须依附于一个Outer Class外部类的对象实例 

外部类和内部类:

public class Outer {private String name = "zkt";private static int VALUE = 18;public static void todo() {System.out.println("这个是外部类的todo方法");}public void test() {System.out.println("这个是外部类的test方法");}public Outer() {}static {System.out.println("这个是外部类的静态代码块");}class Inner {String name = "zkt1";public static final int VALUE1 = 18;//		不能有静态变量
//		private static  int  VALUE1 = 18;//		内部类不能有静态的方法
//		public static void todo1() {
//			System.out.println("这个是内部类的todo1方法");
//		}//		不能有静态代码块
//		static{
//			System.out.println("这个是内部类的构造代码块");
//		}// this调用内部类自己的成员变量// 外部类名.this.成员变量名public Inner(String name) {this.name = name;Outer.this.name = name;}public void todo() {System.out.println("这个是内部类的todo方法");}// 局部>内部成员变量>外部成员变量public void sayHello() {System.out.println("局部name:" + name);System.out.println("内部成员name:" + this.name);System.out.println("外部成员name:" + Outer.this.name);System.out.println(VALUE);System.out.println(VALUE1);Outer.todo();test();}}}

创建方式1:

//1.需要先定义出来外部类的对象,通过外部类的对象去创建内部类对象Outer out = new Outer();Outer.Inner inner = out.new Inner("张三");inner.sayHello();

创建方式2:

//2.内部类对象创建方法2Inner  inner1 = new Outer().new Inner("李四");inner1.sayHello();System.out.println(Inner.VALUE1);

Inner Class和普通Class相比,除了能引用Outer实例外,还有一个额外的“特权”,就是可以修改Outer Class的private字段,因为Inner Class的作用域在Outer Class内部,所以能访问Outer Class的private字段和方法。


观察Java编译器编译后的.class文件可以发现,Outer类被编译为Outer.class,而Inner类被编译为Outer$Inner.class。

2. Anonymous Class 匿名类

还有一种定义Inner Class的方法,它不需要在Outer Class中明确地定义这个Class,而是在方法内部,通过匿名类(Anonymous Class)来定义。

Outer类:

public class Outer1 {private String name;public Outer1(String name) {this.name = name;}public void test() {System.out.println("这个是我的test方法");//Runnable是一个接口,无法实例化对象//{}内的为Runnable接口重写其内部方法的过程,是一个匿名类//通过赋值向上声明成Runnable类型Runnable  runs = new Runnable() {@Overridepublic void run() {System.out.println("这个是run方法"+name);}};new Thread(runs).start();}}

Demo02类:

//匿名内部类
public class Demo02 {public static void main(String[] args) {Outer1 out = new Outer1("zkt");out.test();}
}运行结果:
这个是我的test方法
这个是run方法zkt

观察test()方法,我们在方法内部实例化了一个Runnable。Runnable本身是接口,接口是不能实例化的,所以这里实际上是定义了一个实现了Runnable接口的匿名类,并且通过new实例化该匿名类,然后转型为Runnable。

匿名类和Inner Class一样,可以访问Outer Class的private字段和方法。之所以我们要定义匿名类,是因为在这里我们通常不关心这个类的定义,并且该类仅在定义的位置一次性使用,比直接定义Inner Class可以少写很多代码。

3. Static Nested Class静态内部类

最后一种内部类和Inner Class类似,但是使用static修饰,称为静态内部类(Static Nested Class):

内部类使用原因:
1.内部类对象可以访问创建它的对象实现,包含私有数据
2.对同一个包中的其他类,内部类可以隐藏
3.内部类方法定义和回调
4.使用内部类可以更加优雅的设计程序结构

//1.静态内部类,内部类被static修饰
//2.静态内部类不依附于外部类的对象,无法使用外部类.this方法或者成员变量
//3.静态内部类可以访问静态的成员变量和方法
public class Outer2 {public int age = 19;public static String nameString = "zkt1";static {System.out.println("这个是我外部类的静态代码块");}public static void test() {System.out.println("这个是外部类的静态方法");}static class Inner2 {public int age1 = 13;public static String nameString = "zkt1";static {System.out.println("这个是我内部类的静态代码块");}public static void todo() {System.out.println("这个是内部类的静态方法");Outer2.nameString = "zkt2";System.out.println(Outer2.nameString);System.out.println(nameString);test();}public void eat() {System.out.println("这个是内部类的eat方法");}}}
public class Demo03 {public static void main(String[] args) {
//		Outer2.Inner2 in2 = new Outer2.Inner2();	
//		in2.todo();//静态方法Outer2.Inner2.todo();}
}运行结果:
这个是我内部类的静态代码块
这个是内部类的静态方法
这个是我外部类的静态代码块
zkt2
zkt1
这个是外部类的静态方法

用static修饰的内部类和Inner Class有很大的不同,它不再依附于Outer的实例,而是一个完全独立的类,因此无法引用Outer.this,但它可以访问Outer的private静态字段和静态方法。如果把StaticNested移到Outer之外,就失去了访问private的权限。

这篇关于Java基础14(Enum 枚举类 BigInteger类BigDecimal类 内部类)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/996538

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与

Spring Boot spring-boot-maven-plugin 参数配置详解(最新推荐)

《SpringBootspring-boot-maven-plugin参数配置详解(最新推荐)》文章介绍了SpringBootMaven插件的5个核心目标(repackage、run、start... 目录一 spring-boot-maven-plugin 插件的5个Goals二 应用场景1 重新打包应用

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Spring Boot集成Druid实现数据源管理与监控的详细步骤

《SpringBoot集成Druid实现数据源管理与监控的详细步骤》本文介绍如何在SpringBoot项目中集成Druid数据库连接池,包括环境搭建、Maven依赖配置、SpringBoot配置文件... 目录1. 引言1.1 环境准备1.2 Druid介绍2. 配置Druid连接池3. 查看Druid监控

Java中读取YAML文件配置信息常见问题及解决方法

《Java中读取YAML文件配置信息常见问题及解决方法》:本文主要介绍Java中读取YAML文件配置信息常见问题及解决方法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要... 目录1 使用Spring Boot的@ConfigurationProperties2. 使用@Valu

创建Java keystore文件的完整指南及详细步骤

《创建Javakeystore文件的完整指南及详细步骤》本文详解Java中keystore的创建与配置,涵盖私钥管理、自签名与CA证书生成、SSL/TLS应用,强调安全存储及验证机制,确保通信加密和... 目录1. 秘密键(私钥)的理解与管理私钥的定义与重要性私钥的管理策略私钥的生成与存储2. 证书的创建与

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

linux解压缩 xxx.jar文件进行内部操作过程

《linux解压缩xxx.jar文件进行内部操作过程》:本文主要介绍linux解压缩xxx.jar文件进行内部操作,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、解压文件二、压缩文件总结一、解压文件1、把 xxx.jar 文件放在服务器上,并进入当前目录#

SpringBoot中如何使用Assert进行断言校验

《SpringBoot中如何使用Assert进行断言校验》Java提供了内置的assert机制,而Spring框架也提供了更强大的Assert工具类来帮助开发者进行参数校验和状态检查,下... 目录前言一、Java 原生assert简介1.1 使用方式1.2 示例代码1.3 优缺点分析二、Spring Fr