包装类
-
理解:基本数据类型对应的类
-
出现原因:
-
Java为纯面向对象语言,8种基本数据类型不能new对象,
-
破坏了Java为纯面向对象语言的特征,所以Java有为8种
-
基本数据类型分别匹配了对应的类,这种类叫做包装类/封装类
基本数据类型 | 引用数据类型 | 继承关系 |
---|---|---|
byte | Byte | Object.Number.Byte |
short | Short | Object.Number.Short |
int | Integer | Object.Number.Integer |
long | Long | Object.Number.Long |
float | Float | Object.Number.Float |
double | Double | Object.Number.Double |
char | Character | Object.Character |
boolean | Boolean | Object.Boolean |
注意:
int类型对应的包装类是Integer
char类型对应的包装类是Character
其余的基本数据类型对应的包装类就是首字母大写
-
应用场景:
-
一个方法既可以接收整数也可以接收小数的参数,就可以把形参的类型设置为Number
-
集合作为容器,需要设置元素的参数,元素参数必须是引用数据类型,如果想存储基本数据类型,就可以把元素类型设置为对应的包装类
-
public static void main(String[] args) { /* double i=100.145; Double valueOf = Double.valueOf(i); System.out.println(valueOf); //手动拆箱 包装型->基本数据类型 Double double1 = new Double(120.365); double doubleValue = double1.doubleValue(); System.out.println(doubleValue);*/ //自动拆箱 int i=200; Integer integer=i; System.out.println(integer); //自动拆箱 Double double1 = new Double(365.365); double a=double1; System.out.println(a); //parseInt():将字符串转换为int值 String str = "123"; int num = Integer.parseInt(str); System.out.println(num+1);//124 }
Integer底层
//手写Integer方法创建MyInteger类 package com.qf.package_class; public class MyInteger{ private int value; public MyInteger(int value) { this.value = value; } public int intValue(){ return value; } @Override public String toString() { return String.valueOf(value); } public static MyInteger valueOf(int i){ if(i >= MyIntegerCache.low && i<= MyIntegerCache.high){ return MyIntegerCache.cache[i - MyIntegerCache.low]; } return new MyInteger(i); } //MyInteger缓存类 -- 存储了-128~127区间的MyInteger对象 private static class MyIntegerCache{ private static final int low = -128; private static final int high = 127; private static final MyInteger[] cache; static{ cache = new MyInteger[high - low + 1];//创建数组共有256个元素(有0) int j = low//把最小值当作数组的第一个元素 for (int i = 0; i < cache.length; i++) { cache[i] = new MyInteger(j); j++; } } } } //创建一个测试类 package com.qf.package_class; public class Test03 { /** * 知识点:Integer的深入 -- 底层原理 */ public static void main(String[] args) { // Integer integer = new Integer(100); // int i = integer.intValue(); // System.out.println(i);//100 // System.out.println(integer);//100 系统的Integer Integer integer1 = Integer.valueOf(100); Integer integer2 = Integer.valueOf(100); System.out.println(integer1 == integer2);//true Integer integer3 = Integer.valueOf(200); Integer integer4 = Integer.valueOf(200); System.out.println(integer3 == integer4);//false System.out.println("-------------------------------------"); // MyInteger myInteger = new MyInteger(100); // int i = myInteger.intValue(); // System.out.println(i);//100 // System.out.println(myInteger);//100 自己手写的MyInteger也能实现功能 MyInteger myInteger1 = MyInteger.valueOf(100); MyInteger myInteger2 = MyInteger.valueOf(100); System.out.println(myInteger1 == myInteger2);//true MyInteger myInteger3 = MyInteger.valueOf(200); MyInteger myInteger4 = MyInteger.valueOf(200); System.out.println(myInteger3 == myInteger4);//false } }
枚举
特点
枚举就是一个受限制的类,默认继承Enum
枚举的第一行必须定义该枚举类型的对象
枚举类型对象默认添加: public static final 类型
枚举没有继承明确类(自定义枚举类默认继承Enum,Enum默认继承Object)
枚举类不能被继承
枚举里可以有构造方法、成员方法、静态方法、抽象方法
枚举可以实现接口
枚举里没有定义方法,可以在最后一个对象后面加逗号、分号或什么都不加
优势
增强代码可读性
枚举型可直接与数据库交互
switch语句优势
编译优势
(枚举类编译时,没有把常量值编译到代码中,即使常量值发生改变,也不会影响引用常量的类 )
将常量组织起来,统一管理
去除equals两者判断 由于常量值地址唯一,使用枚举可以直接通过“==”进行两个值之间的对比,性能会有所提高
枚举的方法
方法名 | 解释 |
---|---|
Enum.valueOf(Class<E> enumType, String name) | 根据字符串找到该枚举类中的对象 |
public static void values() | 获取该枚举类对象数组 |
public static void valueOf(String args0) | 根据字符串获取该枚举类中的对象 |
public final String name() | 获取该枚举对象名字 |
public final Class<E> getDeclaringClass() | 获取枚举对象的枚举类型相对应的Class对象 |
public final int hashCode() | 获取该枚举对象的hash值 |
public final int compareTo(E o) | 两个枚举对象进行比较 |
public final boolean equals(Object other) | 比较两个枚举对象是否相同 |
需求:编写季节类(Season),该类只有四个对象(spring,summer,autumn,winter)
重点:只有四个对象 枚举的应用场景:一个类有固定的几个对象,就推荐使用枚举
枚举默认写了 public static final
//创建枚举 package com.qf.enum2; public enum Season { //注意这里是enum不是class类 //底层实现:public static final Season spring = new Season("春天","春雨绵绵"); spring("春天","春雨绵绵"), summer("夏天","烈日炎炎"), autumn("秋天","硕果累累"), winter("冬天","白雪皑皑"); //必须先创建枚举对象可以不写也可以逗号也可以分号结束 private String name; private String info; private Season() { } private Season(String name, String info) { this.name = name; this.info = info; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getInfo() { return info; } public void setInfo(String info) { this.info = info; } @Override//重写toString方法 public String toString() { return name+" "+info; } } //创建一个测试类输出春夏秋冬及其他信息 public class Test01 { public static void main(String[] args) { System.out.println(Season.spring); System.out.println(Season.summer); System.out.println(Season.autumn); System.out.println(Season.winter); } }
枚举的底层
//还是刚才Season的代码反编译 public abstract class Enum<E extends Enum<E>> implements Comparable<E>, Serializable { private final String name;//枚举对象名 private final int ordinal;//枚举对象编号(从0开始) protected Enum(String name, int ordinal) { this.name = name; this.ordinal = ordinal; } public final String name() { return name; } public final int ordinal() { return ordinal; } } /// public final class Season extends Enum{ public static final Season spring; public static final Season summer; public static final Season autumn; public static final Season winter; private String name; private String info; private static final Season[] ENUM$VALUES;//枚举数组 static{ //初始化该枚举类的四个对象,并且把枚举名和枚举编号一并记录下来 spring = new Season("spring", 0, "春天", "春雨绵绵"); summer = new Season("summer", 1, "夏天", "烈日炎炎"); autumn = new Season("autumn", 2, "秋天", "硕果累累"); winter = new Season("winter", 3, "冬天", "白雪皑皑"); //初始化枚举数组 ENUM$VALUES = new Season[]{spring, summer, autumn, winter}; } //private Season(){} private Season(String s, int i){ super(s, i); } //private Season(String name, String info){} private Season(String s, int i, String name, String info){ super(s, i); this.name = name; this.info = info; } public String getName(){ return name; } public void setName(String name){ this.name = name; } public String getInfo(){ return info; } public void setInfo(String info){ this.info = info; } public String toString(){ return (new StringBuilder(String.valueOf(name))).append(" -- ").append(info).toString(); } //获取该枚举类所有的对象 public static Season[] values(){ Season[] aseason = ENUM$VALUES; int i = aseason.length; Season[] aseason1 = new Season[i]; //参数 - 源数组,开始下标,目标数组,开始下标,拷贝长度 System.arraycopy(aseason, 0, aseason1, 0, i); return aseason1; } public static Season valueOf(String s){ return (Season)Enum.valueOf(com/qf/enum03/Season, s); } } //测试类 package com.qf.enum03; public class Test01 { /** * 知识点:枚举的方法 */ public static void main(String[] args) { //通过字符串获取对应枚举类里的对象 Season season1 = Enum.valueOf(Season.class, "spring"); //通过字符串获取对应枚举类里的对象 Season season2 = Season.valueOf("spring"); System.out.println(season1 == season2);//true //获取枚举对象名 String name1 = season1.name(); String name2 = season2.name(); System.out.println(name1); System.out.println(name2); //获取枚举对象编号 int ordinal1 = season1.ordinal(); int ordinal2 = season2.ordinal(); System.out.println(ordinal1);//0 System.out.println(ordinal2);//0 //获取该枚举类里所有的对象 Season[] seasons = Season.values(); for (Season season : seasons) { System.out.println(season); } } }