一、Object 类
所有的类,都直接或者间接的继承了 Object 类 ,Object类的方法是一切子类都可以直接使用
的。
Object类的常用方法:
1.public String toString()
默认是返回当前对象在堆内存中的地址信息:类的全限名@内存地址(十六进制哈希值)
① 底层代码:
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
getClass().getName() : 类名称, 全类名(包名 + 类名)
Integer.toHexString() : 转十六进制
hashCode() : 返回的是对象内存地址 + 哈希算法, 算出来的整数 (哈希值)
② 存在的意义:
toString() 方法存在的意义就是为了被子类重写,以便返回对象的内容信息,而不是地址
信息!!
public class Main {
public static void main(String[] args) {
A a = new A();
System.out.println( a.toString());
}
}
class A {
@Override
public String toString() {
return "重写后toString方法";
}
}
注意: 使用打印语句, 打印对象名的时候, println方法, 源码层面, 会自动调用该对象的
toString方法.
//打印方法的底层代码
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
2.public Boolean equals(Object o)
默认是比较当前对象与另一个对象的地址是否相同,相同返回true,不同返回false
存在的意义:
equals方法存在的意义就是为了被子类重写,以便子类自己来定制比较规则。
重写的快捷键——右键点击Generate -> equals() and hashCode()
public boolean equals(Object o) {
//先判断地址是否相同,如果相同,直接返回true
if (this == o) return true;
/*
判断传出的值是否是null,如果是,直接返回false,如果不是,继续判断
getClass() != o.getClass():两个对象的字节码是否相同,如果不相同直接返
回false,如果相同意味着类型相同,继续向下判断
*/
if (o == null || getClass() != o.getClass()) return false;
//对参数进行强转,向下转型
Student student = (Student) o;
//判断内部元素是否相同
return age == student.age && Objects.equals(name, student.name);
}
3.public static boolean equals(Object a, Object b)
比较两个对象的,底层会先进行非空判断,从而可以避免空指针异常。再进行equals比
较
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
① a == b : 如果地址相同, 就会返回为true, 这里使用的符号是短路 || , 左边为true, 右边
就不执行了
- 结论: 如果地址相同, 方法直接返回为true
: 如果地址不相同, 就会返回false, 短路 || , 左边为false, 右边要继续执行.
② a != null : 假设 a 是 null 值
null != null : false
&& : 左边为false, 右边不执行, 右边不执行, 记录着null值的a, 就不会调用equals方
法
- 避免空指针异常 !
③ a != null : 假设 a 不是 null 值
a != null : true
&& : 左边为true, 右边继续执行, a.equals(b), 这里就不会出现空指针异常
4.public static boolean isNull(Object obj)
判断变量是否为 null
二、Math 类
包含执行基本数字运算的方法
方法名 | 说明 |
public static int abs(int a) | 获取参数绝对值 |
public static double ceil(double a) | 向上取整 |
public static double floor(double a) | 向下取整 |
public static int round(float a) | 四舍五入 |
public static int max(int a,int b) | 获取两个int值中的较大值 |
public static double pow(double a,double b) | 返回a的b次幂的值 |
public static double random() | 返回值为double的随机值,范围[0.0,1.0) |
三、System 类
System的功能是静态的,都是直接用类名调用即可
1.public static void exit(int status)
终止当前运行的 Java 虚拟机,非零表示异常终止
2.public static long currentTimeMillis()
返回当前系统的时间毫秒值形式
(计算机中的时间原点,1970年1月1日 08:00:00算C语言的生日)
3.public static void arraycopy(数据源数组, 起始索引, 目的地数组, 起始索引, 拷贝个数)
数组拷贝
int[] arr = {11,22,33,44,55}; //建立数组
int[] destArr = new int[3];//建立数据接收拷贝值
/*拷贝从下标为2的数组开始拷贝arr中的的数据到destArr中,从destArr的0号索引开始放
入,一共拷贝三个元素*/
System.arraycopy(arr, 2, destArr, 0, 3);
for (int i = 0; i < destArr.length; i++) {
System.out.println(destArr[i]);//遍历打印数组
}
四、BigDecimal 类
用于解决小数运算中, 出现的不精确问题
public class BigDecimalDemo {
public static void main(String[] args) {
double num1 = 0.1;
double num2 = 0.2;
System.out.println(num1 + num2);
}
}
BigDecimal创建类的方法:
public BigDecimal(double val) 不推荐, 无法保证小数运算的精确 |
public BigDecimal(String val) |
public static BigDecimal valueOf(double val) |
BigDecimal常用成员方法 :
public BigDecimal add(BigDecimal b) : 加法
public BigDecimal subtract(BigDecimal b) : 减法
public BigDecimal multiply(BigDecimal b) : 乘法
public BigDecimal divide(BigDecimal b) : 除法
public BigDecimal divide (另一个BigDecimal对象,精确几位,舍入模式) : 除法
BigDecimal divide = bd1.divide(参与运算的对象, 小数点后精确到多少位, 舍入模式);
舍入模式: RoundingMode.UP 进一法
RoundingMode.DOWN 去尾法
RoundingMode.HALF_UP 四舍五入
注意: 如果使用BigDecimal运算, 出现了除不尽的情况, 就会出现异常,所以建议传入所
有的参数
五、包装类
将基本数据类型, 包装成类 (变成引用数据类型)(红色为重点)
基本数据类型 | 引用数据类型 |
byte | Byte |
short | Short |
int | Integer |
long | Long |
char | Character |
float | Float |
double | Double |
boolean | Boolean |
手动装箱:
调用方法, 手动将基本数据类型, 包装成类
1. public Integer(int value) : 通过构造方法 (不推荐)
2. public static Integer valueOf(int i) : 通过静态方法
手动拆箱:
调用方法, 手动将包装类, 拆成(转换)基本数据类型
1. public int intValue() : 以 int 类型返回该 Integer 的值
JDK5版本开始, 出现了自动拆装箱 :
1. 自动装箱 : 可以将基本数据类型, 直接赋值给包装类的变量
int num = 10;
Integer i1 = num;
2. 自动拆箱 : 可以将包装类的数据, 直接赋值给基本数据类型变量
int i = i1;
结论: 基本数据类型, 和对应的包装类, 可以直接做运算了, 不需要操心转换的问题了
Integer 常用方法 :
public static String toBinaryString (int i) : 转二进制
public static String toOctalString (int i) : 转八进制
public static String toHexString (int i) : 转十六进制
public static int parseInt (String s) : 将数字字符串, 转换为数字
例:
int num = 100;
System.out.println(Integer.toBinaryString(num));//1100100
System.out.println(Integer.toOctalString(num));//144
System.out.println(Integer.toHexString(num));//64
String s = "123";
System.out.println(Integer.parseInt(s) + 100); // 223
练习:
已知字符串 String s = "10,50,30,20,40"; 请将该字符串转换为整数并存入数组
随后求出最大值打印在控制台
String s = "10,50,30,20,40";
// 1. 根据逗号做切割
String[] sArr = s.split(",");
// 2. 准备一个整数数组, 准备存储转换后的数字
int[] nums = new int[sArr.length];
// 3. 遍历字符串数组
for (int i = 0; i < sArr.length; i++) {
// sArr[i] : 每一个数字字符串
// 4. 将数字字符串转换为整数, 并存入数组
nums[i] = Integer.parseInt(sArr[i]);
}
// 5. 求最大值
int max = nums[0];
for (int i = 1; i < nums.length; i++) {
if(nums[i] > max){
max = nums[i];
}
}
System.out.println("最大值为:" + max);
面试题:
public class IntegerDemo {
public static void main(String[] args) {
Integer i1 = 127;
Integer i2 = 127;
System.out.println(i1 == i2);
Integer i3 = 129;
Integer i4 = 129;
System.out.println(i3 == i4);
}
}
上述代码两次输出的结果分别是什么?
答:true false
解析:自动装箱的时候, 如果装箱的数据范围, 是-128~127, ==号比较的结果就是true, 反之都
是false,自动装箱的原理 : 自动帮我们调用了 Integer.valueOf(127);
// i = 127,valueOf的源码
public static Integer valueOf(int i) {
if (i >= -128 && i <= 127) {//i >= IntegerCache.low && i <= IntegerCache.high
return IntegerCache.cache[255];//[i + (-IntegerCache.low)]
}
return new Integer(i);
}
源码封装的IntegerCache.low是-128,127+128 = 255
如果装箱的数据, 不在 -128 ~ 127 之间, 会重新创建新的对象
如果装箱的数据, 在 -128 ~ 127 之间, 不会创建新的对象, 而是从底层的数组中, 取出一个
提前创建好的Integer对象, 返回
- Integer类中, 底层存在一个长度为256个大小的数组, Integer[] cache
在数组中, 存储了256个Integer对象, 分别是 -128 ~ 127