包装类
介绍
java中为8种基本数据类型又对应准备了8种包装类型,8种包装类属于引用数据类型,父类是Object。思考:为什么要再提供8种包装类呢?有没有这种需求:调用 doSome() 方法的时候需要传一个数字进去,但是数字属于基本数据类型,而 doSome() 方法参数的类型是 Object ,可见doSome() 方法无法接收基本数据类型的数字,那怎么办呢?可以传一个数字对应的包装类进去。
基本数据类型 | 包装类型 |
byte | java.lang.Byte(父类Number) |
short | java.lang.Short(父类Number) |
int | java.lang.Integer(父类Number) |
long | java.lang.Long(父类Number) |
float | java.lang.Float(父类Number) |
double | java.lang.Double(父类Number) |
boolean | java.lang.Boolean(父类Object) |
char | java.lang.Character(父类Object) |
Number
Number 是一个抽象类,无法实例化对象,前6个基本数据类型对应的包装类的父类是java.lang.Object 下的 java.lang.Number,它的方法如下:
byte byteValue() //以byte形式返回指定的数值
abstract double doubleValue() //以double形式返回指定的数值
abstract float floatValue() //以float形式返回指定的数值
abstract int intValue() //以int形式返回指定的数值
abstract long longValue() //以long形式返回指定的数值
short shortValue() //以short形式返回指定的数值
例子:NumberFormatException
public class IntegerTest01 {
public static void main(String[] args) {
//经过构造方法的包装,基本数据类型123向引用数据类型的转换
//基本数据类型-->引用数据类型(装箱)
Integer i = new Integer(123);
//引用数据类型-->基本数据类型(拆箱)
float f = i.floatValue();
System.out.println(f); //123.0
//不是一个数字可以包装成Integer吗?不能,运行时出现异常
Integer x=new Integer("中文");
}
}
用常量获取最大值和最小值
public class IntegerTest01 {
public static void main(String[] args) {
//通过访问包装类的常量,来获取最大值和最小值
System.out.println("int的最大值是:"+Integer.MAX_VALUE);
System.out.println("int的最小值是:"+Integer.MIN_VALUE);
System.out.println("byte的最大值是:"+Byte.MAX_VALUE);
System.out.println("byte的最小值是:"+Byte.MIN_VALUE);
}
}
自动装箱和自动拆箱
//Java5之后就支持自动装箱和拆箱了,Number类中的方法就用不着了
public class Test01 {
public static void main(String[] args) {
//100是基本数据类型
//x是包装类型
//基本数据类型 --(自动转换)-->包装类型:自动装箱
Integer x=100;//自动装箱调用的是Integer.valueOf(100)
Integer y=100;//由于100在Interger的缓存池范围里,所以调⽤会取得同⼀个对象的引⽤
//x是包装类型
//z是基本数据类型
//包装类型--(自动转换)-->基本数据类型:自动拆箱
int z=x;// 自动拆箱调用了x.intValue()
//x是包装类型,1是基本数据类型
//分析这个为什么没有报错呢?+ - * /等运算会触发自动拆箱机制
System.out.println(x+1); //101
//==比较的是对象的内存地址,x和y两个引用中保存的对象内存地址相同
System.out.println(x==y); //true
}
}
Integer的缓存池
new Integer(127) 与 Integer.valueOf(127) 的区别在于:
- new Integer(127) 每次都会新建⼀个对象
- Integer.valueOf(127) 会使⽤缓存池中的对象,多次调⽤会取得同⼀个对象的引⽤
public class Test01 {
public static void main(String[] args) {
Integer a=128;
Integer b=128;
System.out.println(a==b); //false
/*
Java中为了提高程序的运行执行效率,将[-128~127]之间所有的包装对象提前创建好,
放到了一个方法区的“整数型常量池”当中了,目的是只要用这个区间的数据不需要
再new了,直接从整数型常量池当中取出来,也就是x和y保存的对象的内存地址是一样的。
*/
Integer x=127;
Integer y=127;
System.out.println(x==y); //true
Integer i = new Integer(127);
Integer j = new Integer(127);
System.out.println(i==j); //false
}
}
其他类型的缓存池如下:
- boolean values true and false
- all byte values
- short values between -128 and 127
- int values between -128 and 127
- char in the range \u0000 to \u007F
Integer常用方法
在网页上文本框中输入100(例如百度搜索框),这个100实际上是"100"字符串。后台数据库中要求储存100数字,此时java程序需要将"100"转换成100数字
public class IntegerTest05 {
public static void main(String[] args) {
//装箱
Integer x1 = new Integer(1000); //手动装箱
Integer x2=1000; //自动装箱
Integer x3 = Integer.valueOf(1000);//Integer的静态方法(了解)
Integer x4 = Integer.valueOf("1000");//构造方法参数不同
//拆箱
int y1 = x1.intValue(); //手动拆箱
int y2=Integer.parseInt("1000"); //重点方法
System.out.println(y1); //1000
//编译的时候没问题,一切符合java语法
//不是一个“数字”可以包装成Integer吗?不能,运行时出现异常
//java.lang.NumberFormatException
Integer a = new Integer("123");
//重点方法
//static int parseInt(String s)
//静态方法,传参String,返回int
int retValue = Integer.parseInt("123"); //String-->int
System.out.println(retValue+100);
//照葫芦画瓢
double retValue2 = Double.parseDouble("3.14");
System.out.println(retValue2+1);
float retValue3 = Float.parseFloat("1.0");
System.out.println(retValue3+1);
//以下内容作为了解
//static String toBinaryString(int i)
//静态的:将十进制转换成二进制字符串
String binaryString = Integer.toBinaryString(3);
System.out.println(binaryString); //"11"二进制字符串
//static String toHexString(int i)
//静态的:将十进制转换成十六进制
String hexString = Integer.toHexString(16);
System.out.println(hexString); //10
}
}
日期类
Date相关方法
java.util.Date,以下为例子:
- Date---->String
- String---->Date
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class DateTest01 {
public static void main(String[] args) {
//1.获取系统当前时间(精确到毫秒的系统当前时间)
//直接带调用无参数构造方法就行
Date nowTime = new Date();
System.out.println(nowTime); //Tue Oct 26 11:37:42 CST 2021
//日期可以格式化吗?
//将日期类型Date,按照指定的格式进行转换:Date-->String
//SimpleDateFormat是java包下的,专门负责日期的格式化的
/*
yyyy 年(年是4位)
MM 月(月是2位)
dd 日
HH 时
mm 分
ss 秒
SSS 毫秒(毫秒3位,最高999)
*/
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
String nowTimeStr = sdf.format(nowTime);
System.out.println(nowTimeStr); //2021/10/26 11:49:20:957
//2.假设现在有一个日期字符串String,怎么转换成Date类型?
String time = "2008/12/12 08:08:20:555";
//格式不能随便写,要和上面的日期字符串格式相同
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss:SSS");
try {
Date dateTime = sdf2.parse(time);
System.out.println(dateTime); //Fri Dec 12 08:08:20 CST 2008
} catch (ParseException e) {
e.printStackTrace();
}
}
}
统计毫秒
简单总结一下System的相关属性和方法:
- System.out [out是System类的静态变量]
- System.out.println [println()方法不是System类的,是PrintStream类的方法]
- System.gc() 建议启动垃圾回收器
- System.currentTimeMills() 获取自1970年1月1日到系统当前时间的总毫秒数
- System.exit(0) 退出JVM
public class DateTest02 {
public static void main(String[] args) {
//获取自1970年1月1日 00:00:00 000到当前系统时间的总毫秒数
long nowTimeMillis = System.currentTimeMillis();
System.out.println(nowTimeMillis); //1635221774684
//统计一个方法耗时
//在调用目标方法之前记录一个毫秒数
long begin = System.currentTimeMillis();
print();
//在执行完目标方法之后记录一个毫秒数
long end = System.currentTimeMillis();
System.out.println("耗费时长"+(end-begin)+"毫秒"); //耗费时长21毫秒(每次结果都一样,例如有13的)
}
//需求:统计一个方法执行所耗费的时长
public static void print(){
for(int i=0;i<1000;i++){
System.out.println("i="+i);
}
}
}
毫秒与Date
public class DateTest03 {
public static void main(String[] args) {
//参数是毫秒 以时间1970-01-01 00:00:00 000为起点
Date d1 = new Date(1);
SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss SSS");
String str1 = sdf1.format(d1);
System.out.println(str1); //1970/01/01 08:00:00 001(北京是东八区,差八个小时)
//获取昨天的此时的时间
Date d2 = new Date(System.currentTimeMillis() - 1000 * 60 * 60 * 24);
String str2 = sdf1.format(d2);
System.out.println(str2);
}
}
数字格式化
java.text.DecimalFormat专门负责数字格式化的,数字格式有以下格式:
- # 代表任意数字
- , 代表千分位
- . 代表小数点
- 0 代表不够时补零
public class DecimalFormatTest01 {
public static void main(String[] args) {
DecimalFormat df1 = new DecimalFormat("###,###.##");
String s1 = df1.format(1234.56123);
System.out.println(s1); //1,234.56
DecimalFormat df2 = new DecimalFormat("###,###.0000");
String s2 = df2.format(1234.56);
System.out.println(s2); //1,234.5600
}
}
BigDecimal 属于大数据,精度极高。不属于基本数据类型,属于java对象(引用数据类型)这是SUN提供的一个类。专门用在财务软件当中。注意:财务软件中double是不够的,如果面试问:要处理财务数据要使用哪种类型,不能说double,要回答java,math.BigDecimal
public class BigDecimalTest01 {
public static void main(String[] args) {
//这里不是普通的数字100,,而是精度极高的100
BigDecimal v1 = new BigDecimal(100);
BigDecimal v2 = new BigDecimal(200);
//引用不能直接用+求和
BigDecimal v3 = v1.add(v2);
System.out.println(v3);//300
BigDecimal v4 = v2.divide(v1);
System.out.println(v4);//2
}
}
Random
产生随机数
import java.util.Random;
public class RandomTest01 {
public static void main(String[] args) {
Random random = new Random();
int num1 = random.nextInt();
//随机产生一个int类型取值范围内的数字
System.out.println(num1);
//产生[0~100]之间的随机数,不能产生101
random.nextInt(101);
}
}
enum枚举类
例1
下面的案例没有使用Java中的枚举,分析以下程序,在设计方面有什么缺陷?
public class EnumTest01 {
public static void main(String[] args) {
int retValue1 = divide(10,2);
System.out.println(retValue1==1?"计算成功":"计算失败");// 1
int retValue2 = divide(10,0);
System.out.println(retValue2==0?"计算成功":"计算失败");// 0
}
/**
*以下程序,计算两个int类型数据的商,计算成功返回1,计算失败返回0
* @param a 被除数
* @param b 除数
* @return 返回1表示成功,返回0表示失败
*/
public static int divide(int a, int b) {
try{
int c=a/b;
//程序执行到此处表示以上代码没有发生异常,表示执行成功
return 1;
}catch(Exception e){
//执行到此处表示以上程序出现了异常
return 0;
}
}
}
例2
答:既然只有两个结果,最好使用布尔类型,或者使用下面的enum类:
- 枚举:一枚一枚可以列举出来的,才建议使用枚举类型
- 枚举编译之后也是生成class文件
- 枚举也是一种引用数据类型
- 枚举中的每一个值可以看做是常量
public class EnumTest02 {
public static void main(String[] args) {
Result retValue1 = divide(10,2);
System.out.println(retValue1==Result.SUCCESS?"计算成功":"计算失败");// 1
Result retValue2 = divide(10,0);
System.out.println(retValue2==Result.FAIL?"计算成功":"计算失败");// 0
}
public static Result divide(int a, int b) {
try{
int c=a/b;
//程序执行到此处表示以上代码没有发生异常,表示执行成功
return Result.SUCCESS;
}catch(Exception e){
//执行到此处表示以上程序出现了异常
return Result.FAIL;
}
}
}
enum Result{
SUCCESS,FAIL
}
例3
enum使用场合:四季、颜色、星期
public enum Season{
SPRING,SUMMER,AUTUMN,WINTER
}
public enum RGB{
RED,GREEN,BLUE
}
public class SwitchTest {
public static void main(String[] args) {
switch (Season.SPRING){
//java: 枚举 switch case 标签必须为枚举常量的非限定名称
case SPRING:
System.out.println("春天");
break;
case SUMMER:
System.out.println("夏天");
break;
case AUTUMN:
System.out.println("秋天");
break;
case WINTER:
System.out.println("冬天");
break;
}
}
}