一、Object类
1.Object类介绍
(1) Object类位于java.lang包中,是继承关系的根类、超类,是所有类的父类(直接父类或是间接父类)
(2) Object类型的引用可以用于存储任意类型的对象。
(3) Object类中定义方法,所有类都可以直接使用。
2.Object类中常用方法
(1) getClass()
返回引用中实际存储的对象类型。
应用:用于判断两个引用中实际存储的对象类型是否一致,一致返回true;不一致返回false。
class Animal{}
class Dog extends Animal{}
class Cat extends Animal{}
//案例
Animal a1 = new Cat();
Animal a2 = new Dog();
System.out.println(a1.getClass() == a2.getClass());
(2) int hashCode()
返回对象的整数哈希码值。对象的哈希码值来源是将十六进制的地址,转换为十进制的整数结果。
注意:不同对象在堆内存中有不同十六进制地址,所以不同对象一般具有不同哈希码值。
(3) String toString()
返回该对象字符串的表现形式。【开发重点】
a. 作用:方便展示对象信息,子类通常需要重写toString方法。重写原则:一般将对象所有属性拼接为一串字符串返回。
b. 重写示例:
public String toString(){
return "name="+name+",age="+age;
}
c. get方法和toString区别:
Ⅰ.get方法:返回对象单个属性,不会改变属性数据类型
Ⅱ.toString:获取对象全部属性信息,统一拼接为String类型返回
(4) boolean equals(Object o)
用于比较对象内容是否相同。【开发应用重点】
a. == 的应用
Ⅰ. ==两端为基本数据类型变量:比较变量存储的数值是否相同;
==两端为引用类型变量:比较引用存储的内存地址是否相同。
Ⅱ.开发场景:引用类型使用==,一般用来判断两个引用是否指向同一个对象。
引用名1 == 引用名2:true代表指向同一个对象;false代表指向不同对象。
b. equals方法应用
Ⅰ.Object父类中equals底层源码:
public boolean equals(Object obj){
return (this == obj);
}
说明:父类原生equals本质还是用==比较地址,只能判断是否为同一个对象;开发中大多需要对比对象属性内容,因此子类必须重写equals。
Ⅱ.equals标准重写模板:
public boolean equals(Object obj){
//1.自反性:判断当前对象和传入对象是否为同一个
if(this == obj){
return true;
}
//2.判断传入对象是否为空
if(obj == null){
return false;
}
//3.判断两个对象实际类型是否一致
if(this.getClass() != obj.getClass()){
return false;
}
//4.强制向下转型,准备对比属性
Student s = (Student)obj;
//5.逐一对比属性:基本类型用==,引用类型调用equals
if(this.age == s.age && this.score == s.score && this.name.equals(s.name)){
return true;
}else{
return false;
}
}
面试重点:== 和 equals区别
1. ==
• 基本数据类型:比较值是否相等
• 引用数据类型:比较内存地址是否相等
2. equals
• Object原生equals:等价于==,只比较地址
• 子类重写后equals:用来比较对象属性内容是否相同
(5) finalize()
JVM执行垃圾回收时自动调用的方法。【面试了解】
a.垃圾对象:没有任何引用指向的对象
Student s = new Student();
s = null; //该对象变为垃圾对象
b.垃圾回收器:简称GC,用来回收堆中的垃圾对象
c.回收目的:清除无引用对象,释放堆内存,提升空间利用率
d.两种回收时机:
①自动回收:JVM内存不足、无法分配新对象空间时,GC自动回收所有垃圾对象,回收前自动执行finalize()
②手动提醒回收:System.gc();仅通知GC执行回收,GC空闲才会执行,繁忙则暂缓回收
⚠注意:finalize执行时机不可控,不要在该方法编写核心业务代码。
二、包装类(java.lang包)
1.概念
八种基本数据类型,各自对应的引用类型,就是包装类。
2.基本类型与对应包装类对照表
基本数据类型 包装类类名
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
3.数据互相转换
(1) int ↔ Integer
int转Integer:
//方式1:构造方法
Integer i1 = new Integer(12);
//方式2:静态方法valueOf()
Integer i2 = Integer.valueOf(12);
Integer转int:
int a1 = i1.intValue();
(2) String ↔ Integer
String转Integer:
Integer i3 = new Integer("123");
Integer i4 = Integer.valueOf("123");
Integer转String:
String s1 = i4.toString();
String s2 = i4 + ""; //字符串拼接方式
(3) int ↔ String
int转String:
int a = 3;
String s3 = a + "";
String转int【开发常用】
int a = Integer.parseInt("123");
⚠注意:转换的字符串必须是纯数字格式,否则抛出NumberFormatException数字格式转换异常。
4.自动装箱、自动拆箱
(1) JDK5.0新增特性,基本类型和对应包装类可以自动互相转换
• 自动装箱:基本类型 → 包装类型
• 自动拆箱:包装类型 → 基本类型
Integer i = 12; //自动装箱
int a = i; //自动拆箱
(2) 底层原理:自动装箱本质调用Integer.valueOf()
public static Integer valueOf(int i){
//缓存范围:-128 ~ 127
if(i >= -128 && i <= 127){
return IntegerCache.cache[i + (-IntegerCache.low)];
}
return new Integer(i);
}
💡常量池缓存说明:-128~127之间的数据提前存入缓存池,该范围数据装箱直接复用缓存对象;超出范围每次都会new新Integer对象。
面试案例:
Integer i1 = 12;
Integer i2 = 12;
System.out.println(i1==i2); //true,在缓存区间内
Integer i3 = 150;
Integer i4 = 150;
System.out.println(i3==i4); //false,超出缓存区间,创建两个不同对象
5.包装类实际开发作用
(1) 区分有效值和空值:比如区分0 和 null、0.0 和 null;基本类型默认值不为null,包装类默认值为null。
(2) 开发中实体类属性一般定义为包装类,用来区分未赋值(null)和赋值为0的场景。
三、String类【开发重点】
1.两种创建字符串方式
(1) String s1 = "hello";:仅在字符串常量池创建1个对象
(2) String s2 = new String("world");:创建2个对象,堆内存+常量池各1个
⚠常量池已有相同字符串时,不会重复创建。
2.String常用方法
(1) char charAt(int index):根据下标获取对应字符
底层封装char数组,下标范围:0 ~ 字符串长度-1;下标越界抛出StringIndexOutOfBoundsException下标越界异常。
(2) boolean contains(String str):判断当前字符串是否包含子串str,包含返回true。
(3) boolean equals(String str):比较两个字符串内容是否完全相同,开发比较字符串内容必须使用equals,不能用==。
(4) int length():获取字符串字符长度
区分:数组长度:数组名.length;字符串长度:字符串.length()
字符串遍历写法:
String s = "hello";
for(int i = 0; i < s.length(); i++){
char c = s.charAt(i);
System.out.println(c);
}
(5) String trim():去除字符串首尾两端空格
常用场景:接收前端输入内容去除多余空格再转数字
String age = " 18 ";
int n = Integer.parseInt(age.trim());
(6) String[] split(String str):按照指定分隔符拆分字符串,返回String数组。
3.String不可变性【面试题】
(1) String字面量属于常量;字符串拼接操作不会修改原有字符串,而是拷贝一份副本,在副本上完成拼接。
(2) 因为不可变性,频繁字符串拼接运行效率很低。
补充:String s = "a"+"b";编译期优化,编译器直接识别为"ab",只会创建1个常量池对象。
四、可变字符串(java.lang包)
1.两个类区别
• StringBuffer:JDK1.0诞生,线程安全,执行效率偏慢
• StringBuilder:JDK5.0诞生,线程不安全,执行效率更快
2.常用构造方法
//无参构造
public StringBuilder()
//带字符串参数构造
public StringBuilder(String str)
3.核心方法
StringBuilder append(String str):完成字符串拼接,返回自身对象,支持链式拼接。
4.三者面试总结区别
1. String:不可变字符串,拼接效率低;线程安全
2. StringBuilder:可变字符串,拼接效率高;线程不安全(单线程优先使用)
3. StringBuffer:可变字符串,拼接效率较高;线程安全(多线程环境使用)
五、BigDecimal类【了解】
1.包路径
位于java.math包
2.作用
用来精准存储、运算浮点型小数,解决double/float浮点运算丢失精度问题。
3.常用构造方法
public BigDecimal(String n):推荐使用字符串格式创建对象,避免精度丢失。
4.四则运算方法
BigDecimal r1 = bd1.add(bd2); //加法 bd1 + bd2
BigDecimal r2 = bd1.subtract(bd2); //减法 bd1 - bd2
BigDecimal r3 = bd1.multiply(bd2); //乘法 bd1 * bd2
//除法:参数1=除数;参数2=保留小数位数;参数3=取舍模式(ROUND_HALF_UP四舍五入)
BigDecimal r4 = bd1.divide(bd2,2,BigDecimal.ROUND_HALF_UP);