开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第4天,点击查看活动详情
1.枚举:Enum Type
-
如果一个变量的取值只可能是固定的几个值,可以考虑使用枚举类型。(季节、性别、方位)
-
枚举由一组预定义的常量构成。
-
枚举的本质是类,所有枚举类型都隐式继承自java.lang.Enum。
public enum Session{ // 最后一个常量不用加分号 SPRING, SUMMER, FALL, WINTER } // 使用 Session s = Session.WINTER; print(s.name()); // WINTER print(s.ordinal()); // 3 // 如果在switch里,可不用写 Session.XXX,直接写XXX Session session; switch(session){ case SPRING: xxx; break; case SUMMER: xxx; break; }
-
枚举定义完常量后,还可再定义成员变量,方法等。(这时最后一个枚举常量要以分号结束)
-
枚举的构造方法权限必须是 无修饰符 或 private
public enum Session{ SPRING, SUMMER, FALL, WINTER; public int sum = 10; //构造方法私有化,防止外界通过new 方式创建枚举类 private Session(){ xxxx } }
-
java会主动调用构造方法 来初始化每个常量,用户不能主动调用构造方法(因为编译器把构造方法用peivate修饰了)。
//上述的枚举 大致实现如下 public class Session{ private Session(){} // 构造方法 // 调用构造方法 来初始化每个常量 public static final Session SPRING = new Session(); public static final Session SUMMER = new Session(); public static final Session FALL = new Session(); public static final Session WINTER = new Session(); } // 调用 Session s = Session.SPRING if(s == Session.SPRING){ }
1.1.自定义了构造方法 的枚举
public enum Session{
SPRING(5, 15), // 参数分别是 最低、最高温度
SUMMER(25, 35),
FALL(13, 25),
WINTER(-5, 5);
private int min;
private int max;
Session(int min, int max){
this.min = min;
this.max = max;
}
// 提供getter方法
public int getMin(){
return min;
}
public int getMax(){
return max;
}
}
//使用温度
Session s = Session.SPRING;
print(s.getMax()); // 15
print(s.getMin()); // 5
2.包装类
2.1.基本类型的缺陷:
- 无法表示不存在的值(null)
- 不能利用面向对象的方式操作基本类型(如直接用基本类型调用方法)
- 当方法参数是引用类型时,基本类型无法传递。
解决方案:可以自己将基本类型包装成引用类型。
public class IntObject{
private int value;
public IntObject(int value){
this.value = value;
}
//提供Setter/Getter方法
}
//调用
IntObject num = null;
IntObject age = new IntObject(110);
2.2.包装类:Wrapper Class
- java内置了基本数据类型的包装类(java.lang包下)
- 自动装箱:java编译器会自动调用xxx.valueOf()方法,将基本类型转换为包装类(装包)。
- 自动拆箱:java编译器会自动调用xxxValue()方法,将包装类转换为基本类型(拆包)。
Integer num = Integer.valueOf(10);
Integer num = 10; // 自动装箱
Integer max = 10;
int min = max.intValue();
int min = max; // 自动拆箱
2.3.包装类的判等(不要使用 ==、!=,应该使用equals方法。)
DK1.5后, 包装类型Integer、Short、Byte、Character、Long都使用了缓存技术。
// 1.IntegerCache 类中缓存了[-128, 127]范围的Integer对象
// 2.Integer.valueOf方法会优先去IntegerCache缓存中获取Integer对象
// 3. == 判断两边的对象是不是同一个对象
// 直接使用new构造一个长整型的时候,会生成一个新的对象。
// 而使用 valueOf 的时候,如果参数位于[-128, 127]这个区间内,则直接从cache数组中取一个对象。
// 如果不在区间里,则新建对象。
// 自动装箱时,Java调用了valueOf函数,拆箱时,调用 xxxValue 函数。
Integer d1 = 88;
Integer d2 = Integer.valueOf(88); // 与Integer d1 = 88;等价
Integer d3 = new Integer(88);
Long e = 1000L;
Long f = 1000L;
println(d1 == d2); // true 两者都是从缓存中拿数据
println(d1 == d3); // false d3是new对象,数据在堆内存
println(e == f); // false 和Integer一样,未走缓存
// 举例2:
println(((Long)1L) == 1); // true
println(new Long(1).equals(1)); // false
println(new Long(1).equals(1L)); // true
println(((Long)1000L) == 1000); // true
println(((Long)1000L) == Long.valueOf(1000)); // false
// == 操作符的左边是一个Long型的对象,为了比较就使用了自动拆箱,左边拆箱成了整数1,所以与右边的值是相等的。
// 第二行:equals参数接受一个Object对象,所以1就被自动装箱成了Integer.valueOf(1)。
// 而Long的equals的实现:如果传进来的是Long型的,那么就比较值,如果传进来的是其他类型,直接返回false。
2.4.【基本类型数组】与【包装类数组】之间是不能自动装箱、拆箱的。
void test1(Integer[] nums){省略方法体...}
int[] nums1 = {11, 22};
test1(nums1); //error
Integer[] nums2 = {11, 22};
int[] nums3 = nums2; //error
2.5.高精度计算:
float
、double
存储的只是小数的近似值,并非精确值,因此不适合用来做高精度计算。
double d1 = 0.7;
double d2 = 0.7;
//浮点数转化为二进制会出现以下错误
println(d1 * d2); //0.4899999999
建议使用java.math.BigDecimal
来进行高精度计算。
new BigDecimal(0.7); //浮点数本来就不准确,这么传,结果依然不准确
//建议使用字符串初始化BigDecimal
//里面有个字符数组,把每个字符都单独存{'0', '.', '7'}
BigDecimal v1 = new BigDecimal("0.7");
BigDecimal v2 = new BigDecimal("0.7");
println(v1.add(v2)); // 加,1.4
println(v1.subtract(v2)); // 减,0.0
println(v1.multiply(v2)); // 乘,0.49
println(v1.divide(v2)); // 除,1
println(v1.setScale(3)); // 保留3位小数 0.700
字符串与数字互相转化:
-
字符串转数字:使用包装类的
valueOf()
、parseXX()
方法Integer i1 = Integer.valueOf("123"); // 123 int i2 = Integer.parseInt("123"); // 123 int i3 = Integer.parseInt("FF", 16); // 255 (十六进制解析FF) Float i1 = Float.valueOf("12.3"); // 12.3 float i1 = Float.parseFloat("12.3"); // 12.3
-
数字转字符串:使用字符串的
valueOf()
方法,包装类的toString()
方法String str1 = String.valueOf(12.3); // 12.3 String str2 = Integer.toString(123); // 255 String str1 = Integer.toString(255, 16); // FF String str1 = Float.toString(12.3f); // 12.3