枚举
枚举指由一组固定的常量组成的类型
public enum Gender{//性别枚举
MALE,FEMALE;
}
public class Student{
public Gender sex;//枚举类型的变量
}
Student s = new Student();
s.sex=Gender.Male;//使用枚举中的值
s.sex="你好";//编译报错
好处:类型安全,易于输入,代码清晰
理解枚举:
enum和class、interface的地位一样
使用enum定义的枚举类默认继承了java.lang.Enum,而不是继承Object类
枚举类的所有实例都必须放在第一行展示,不需使用new 关键字,不需显式调用构造器。自动添加public static final修饰。
枚举类更加直观,类型安全。如果使用常量类,调用者必须知道常量类的定义常量值,但是他也可以不按照常量传值,开发不确定性比较高,不够安全。而枚举类型,必须是其定义好的类型值,改变值会编译报错。
枚举有更多灵活的用法,定义变量,定义普通方法,构造方法,实现一个或者多个接口等,可以有效的提高代码的整洁性、可读性、可维护性等
枚举的扩展用法
public enum OrderErrorEnum {
// 定义枚举类型带参数(默认都是public static final 常量-都要大写)
// 枚举类中所有的定义都可以看做是实例对象,定义必须写在第一行
// 如果实例有参数,就必须同步定义对应的参数值
ORDER_ERROR_CREATE("1000","创建订单异常"), //这些常量的类型是OrderErrorEnum
ORDER_ERROR_PAY("2000","订单支付异常"),
ORDER_ERROR_CALLBACK("3000","订单回调异常");
// 异常码
private String errorCode;
// 异常描述
private String errorMsg;
public String getErrorCode() {
return errorCode;
}
public void setErrorCode(String errorCode) {
this.errorCode = errorCode;
}
public String getErrorMsg() {
return errorMsg;
}
public void setErrorMsg(String errorMsg) {
this.errorMsg = errorMsg;
}
// 自定义一个带参构造,跟实例保持一致 构造方法是私有的
private OrderErrorEnum(String errorCode, String errorMsg){
this.errorCode = errorCode;
this.errorMsg = errorMsg;
}
// 提供一个普通方法:方便调用者根据异常码获取异常说明
public static String getErrorMsgByCode(String errorCode){
// 遍历枚举 通过OrderErrorEnum.values()实例数组 可以取出每一个实例
for (OrderErrorEnum errorEnum : OrderErrorEnum.values()) {
if(errorEnum.errorCode.equals(errorCode)){
return errorEnum.errorMsg;
}
}
return null;
}
public static void main(String[] args) {
// 异常枚举的用法
// 根据枚举的类型直接使用其异常码和异常说明
System.out.println(OrderErrorEnum.ORDER_ERROR_CREATE.getErrorCode());
System.out.println(OrderErrorEnum.ORDER_ERROR_CREATE.getErrorMsg());
// 已知异常码,获取异常说明
String errCode = "3000";
System.out.println(OrderErrorEnum.getErrorMsgByCode(errCode));
}
}
包装类
基本数据类型的不足
1)java中的基本数据类型int,double等不是对象,只能运算,不能提供通用方法,而像String却可以
比如:字符串"11230"可以直接获取到长度(length()方法),但是int=11230获取长度就不方便
再比如:方法获取参数值为字符串数值"123",如果要进行运算怎么办,不用包装类,不好处理
2)基本数据类型不能用作集合框架的泛型
3)为了弥补这个缺陷,java提供了包装类,包装类都在java.lang包下面
包装类的特点
1)提供了一系列实用的方法,作为基本数据类型对应的“类”的类型,提供了一系列实用的对象操作方法。
2)定义了每种基本数据类型的相关属性,如最大值、最小值、所占位数(1字节=8位)等3)所有包装类都是final类型,不能创建它们的子类
4)JDK1.5后,允许基本数据类型和包装类型进行混合数学运算,包装类并不是用来取代基本数据类型的,在基本数据类型需要用对象表示时使用
基本数据类型和包装类的对应关系
byte-Byte short-Short int-Integer long-Long
float-Float double-Double boolean-Boolean char-Character
Character、Boolean的父类是Object,其他的父类是Number
包装类的常用属性
以Integer为例
System.out.println(Integer.SIZE);
System.out.println(Integer.MAX_VALUE);
System.out.println(Integer.MIN_VALUE);
包装类构造实例
以Integer为例
1、所有包装类都可将与之对应的基本数据类型作为参数,来构造它们的实例
Integer a=new Integer(1);//标准的 使用构造方法
Character ch=new Character(‘a’);//没有String类型的构造方法
2、除Character类外,其他包装类可将一个字符串作为参数构造它们的实例
Integer b=new Integer(“1”);
3、Boolean类构造方法参数为String类型时,若该字符串内容为true(不考虑大小写),则该Boolean对象表示true,否则表示false
Boolean boolean1 = new Boolean(“True”); //true
Boolean boolean2 = new Boolean(“trUe”);//true
Boolean boolean3 = new Boolean(“hello”);//false
Boolean boolean4 = new Boolean(“中”);//false
Boolean boolean5 = new Boolean(“false”);//false
4、当Number包装类构造方法参数为String 类型时,字符串不能为null,且该字符串必须可解析为相应的基本数据类型的数据,否则编译通过,运行时会抛出NumberFormatException异常
异常写法:
Integer integer1 = new Integer("");
Integer integer2 = new Integer(“a”);
Integer integer3 = new Integer(null);
包装类的常用方法
1)valueOf(): 所有包装类都有将对应基本数据类型值变为包装类(基本类型->包装类)
Integer i6 = Integer.valueOf(400);
System.out.println(i6 + 100);
Character c=Character.valueOf('a');
除Character类外,其他包装类都有将对应数值的字符串转为包装类(字符串->包装类)
Integer i7 = Integer.valueOf("5000");
System.out.println(i7 + 100);
// Character c2 = Character.valueOf("A");// 编译报错
2)XXXValue():包装类转换成基本类型(包装类->基本类型)
Integer i3 = new Integer("100");
int int1 = i3.intValue();
System.out.println(int1 + 100);
Double d3 = new Double("100.1");
double double1 = d3.doubleValue();
System.out.println(double1 + 100);
3)toString():以字符串形式返回包装对象表示的基本类型数据(基本类型->字符串)
String s4 = Integer.toString(12345);
// String s4 = new Integer(12345).toString();
System.out.println(s4.length());
// String类中也有一个方法valueOf,可以达到同样的效果
String s5 = String.valueOf(200);
System.out.println(s5 + 100);
4)parseXXX():把字符串转换为相应的基本数据类型数据(Character除外)(字符串->基本类型),注意转换异常:NumberFormatException
int int2 = Integer.parseInt("300");
System.out.println(int2 + 100);
// java.lang.NumberFormatException: For input string: "300.0"
// int int3 = Integer.parseInt("300.0");
装箱和拆箱
装箱 基本类型转换为包装类的对象
Integer i=100;//自动装箱
Integer h =Integer.parseInt(“1”);//装箱
拆箱:包装类转换为基本数据类型
Integer i3 = new Integer(“100”);
int int1 = i3.intValue();
int a=i3;
特殊情况
1、
Double db=new Double("6.2f");//6.2f可以认为是float类型
System.out.println(db);
Long l =new Long("3L");//3L在这里不能看做是long类型的3
System.out.println(l);
2、-128-127 Integer在创建对象时,如果有相同值在缓存中,会返回对象的值,不会创建新的对象
new关键字来创建对象,没有缓存的概念
Integer i=127;会自动装箱为Integer i =Integer.valueOf(127);
Integer i=127;
Integer j=127;
Integer k=new Integer(127);
Integer m=Integer.valueOf(127);
Integer n=Integer.parseInt("127");
System.out.println(i == j);
System.out.println(i == k);
System.out.println(i == m);
System.out.println(i == n);
3、
Integer i=128;
Integer j=128;
Integer k=new Integer(128);
Integer m=Integer.valueOf(128);
Integer n=Integer.parseInt("128");
System.out.println(i == j);
System.out.println(i == k);
System.out.println(i == m);
System.out.println(i == n);
Math
double pi = Math.PI;//圆周率
double e = Math.E;//自然对数的底数
double v = Math.random();//0-1随机数
int a = Math.abs(-12);//绝对值
long b = Math.round(12.4);//四舍五入 long对应double
int c = Math.round(12.6f);//int对应float
System.out.println(Math.floor(12.5));//向下取整
System.out.println(Math.ceil(12.5));//向上取整
System.out.println(Math.sqrt(2));//根号2
System.out.println(Math.log(10));//以e为底的10的对数
System.out.println(Math.log1p(1));//等同于log(1+x)
System.out.println(Math.log10(1));//以10为底的1的对数
Date Calendar SimpleDateFormat
Date
构造方法:Date()、Date(Long date)
Date d=new Date();//获取当前时间
System.out.println(d);
Date d1=new Date(1608336000000L);//时间戳 从1970开始 毫秒
System.out.println(d1);
Date date1 = new Date();
Date date2 = new Date();
System.out.println(date1);
System.out.println(date2);
System.out.println(date1.after(date2));
System.out.println(date2.getTime());//当前时间戳 long
日期加减的方式:
先获取当前时间对象的时间戳,然后计算要加减的毫秒数,再使用构造方法转回时间
Date d=new Date();//获取当前时间
System.out.println(d);
long time =d.getTime()-24*3600*1000;//计算昨天当前的时间戳
Date d1=new Date(time);
System.out.println(d1);
SimpleDateFormat
继承DateFormat类,主要用来进行格式转换
构造函数:SimpleDateFormat(String pattern),最常用的构造方法。根据指定格式来转换字符串与日期
格式化标记:年(yyyy)、月(MM)、日(dd)、时(HH)、分(mm)、秒(ss)、毫秒(SSS)
Date date = new Date(System.currentTimeMillis());//system.currentTimeMillis()获取当前时间毫秒值
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String format = dateFormat.format(date);
System.out.println(format);
public static void main(String[] args) throws ParseException {
Date date1 = new Date();
Date date2 = new Date();
System.out.println(date1);
System.out.println(date2);
System.out.println(date1.after(date2));
System.out.println(date2.getTime());
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String str1 = format.format(date1);
System.out.println(str1);
String str3 = "2020-09-26 16:14:08";
Date date3 = format.parse(str3);//SimpleDateFormat转成Date
//会抛出异常
System.out.println(date3);
}
Calendar
1、 Calendar t= Calendar.getInstance();
//日期和时间
Calendar t= Calendar.getInstance();//抽象类 不能new
//中外时间差异 需要查看帮助文档来确认
System.out.println(t.get(Calendar.YEAR) + "-" + (t.get(Calendar.MONTH) + 1) + "-" + t.get(Calendar.DAY_OF_MONTH));
System.out.println("今天是星期" + (t.get(Calendar.DAY_OF_WEEK) - 1));
2、Calendar c=format.getCalendar();获取最近使用format的日期
Date d=new Date();//获取当前时间
System.out.println(d);
SimpleDateFormat format =new SimpleDateFormat("yyyy/MM/dd/HH:mm:ss");
String time =format.format(d);
System.out.println(time);
Calendar c=format.getCalendar();
Date date =c.getTime();//获取最近使用format的日期 不是时间戳
System.out.println(date);
System.out.println(c.get(Calendar.WEEK_OF_YEAR));