java【三大特殊类:Object类、包装类、String类】

目录

  • 1.Object类
    • 1.1 Object类可以接收所有引用数据类型
    • 1.2 Object 的equals方法
      • 面试题:请解释Java中“==”和 equals 的区别
  • 2.包装类
    • 2.1 包装类和基本类型的相互转换
    • 2.2 包装类型的自动拆装箱
    • 2.3 包装类和基本类型的选取
    • 2.4 包装类的缓存问题

1.Object类

1.1 Object类可以接收所有引用数据类型

Object类是java中所有类的默认父类,所有类默认都继承自Object类,因此使用Object来接收所有类的对象。Object obj=new Class();
除了Object是默认所有类的父类之外,JDK赋予了Object可以接收所有引用数据类型的权利,Object还可以接收数组和接口对象!

int[] arr={1,3,5,7,9};
//1. Object的引用接收数组对象,向上转型
Object obj=arr;
//向下转型
int[] ret=(int[])obj;
System.out.println(Arrays.toString());
//2. Object还可以接收接口对象
IFly fly=new Duck("鸭子");
//向上转型
Object obj1=fly;
//向下转型
IFly fly1=(IFly)obj1;
fly1.fly();

至此,Object已经可以接收所有引用数据类型,只剩下基本数据类型无法处理,因此有了包装类(将基本数据类型的数值封装到一个类中)

1.2 Object 的equals方法

  • 对于基本数据类型,== 表示的是两个变量的数值是否相等
  • 对于引用数据类型,==比较的是两个对象的地址是否相等,若要进行对象内部属性值比较是否相等,使用equals方法(Object类提供的方法)
  1. Object类默认的equals方法
public boolean equals(Object obj)
{
	//将传入对象与当前对象地址进行比较,还在比较地址
	return (this==obj);
}

因此,自定义类中如果要进行当前类中属性的比较,则要进行equals方法的覆写。
2. 覆写equals方法

public Class{
	private String name;
	private int age;
	public boolean equals(Object obj)
	{
	//1. 边界值判断,如果传入对象和当前对象相等
	if(this==obj) return false;
	//2. 如果传入对象为null或者不是person类型的引用对象时
	if(obj==NULL||(obj intanceof person)) return false;
	//3. 此时,证明当前对象和传入对象所指向的是非空,不同类型的person类型引用对象,向下转型进行属性比较
	Person person=(Person)obj;
	return this.age==person.age&&this.name.equals(person.name);
	//注意,此时的equals方法属于String类型的equals方法
	}
}

只要是引用数据类型进行的对象比较,统一使用equals方法,JDK常用的类已经实现好了,String类,包装类,集合类等等

面试题:请解释Java中“==”和 equals 的区别

1.“==”进行的是两个变量数值的比较,对于基本数据类型来说,比较的是具体的数值是否相等;对于引用数据类型来说,比较的是两个引用是否指向同一个对象。
2.“equals”方法进行的是两个类对象的属性值比较,若类的对象要具体比较属性值是否相等,则需要覆写Object类的equals方法。

总结:不同概念或关键字的区别和联系问题如何回答?
若概念之间有关系,先回答共性再分别回答区别;若没有关系,则分开按点介绍即可。

2.包装类

所谓包装类就是将基本数据类型的数值封装到具体的类中
手动实现int包装类。

intClass.java

public class IntClass{
	private int val; 
	//存
	public IntClass(int val)
	{
		this.val=val;
	}
	//取
	public int intVal()
	{
		return this.val;
	}
	public static void main(String[] args)
	{
		IntClass intClass=new IntClass(10);
		int a=intClass.intVal();
		System.out.println(a+1);
	}
}

JDK的包装类

{
	Integer i1=new Integer(10);
	int a=i1.intVal();
	System.out.println(a+1);
}

JDK的包装类分为以下两种:

  • Number 的直接子类:
    整型:byte(Byte) short(Short) int(Integer) long(Long)
    浮点型:float(Float) double(Double)
  • Object 的直接子类
    char–Character
    boolean–Boolean

2.1 包装类和基本类型的相互转换

  • 基本类型–>包装类对象,这个过程称为装箱
    要么通过相应包装类的构造方法或valueof方法(推荐)
  • 包装类对象–>基本类型,这个过程称之为拆箱
    调用相应包装类的xxValue方法实现拆箱
int a=10;
//1. 装箱
Integer i1=Integer.valueOf(a);
//2. 拆箱
int b=i1.intValue();
  • 数值型包装类内部可以实现数据类型的随意转换
    由于任何一个数值型包装类都是属于Number的直接子类,因此任何一个数值型包装类的内部都具备这6个方法的实现,可以方便的将某个类型转为任意的其他类型(注意越界以及丢失精度问题)。
intValueOf();
longValueOf();
floatValueOf();
doubleValueOf();
byteValueOf();
shortValueOf();
int a=10;
//1. 装箱
Integer i1=Integer.valueOf(a);
//2. 拆箱
double d1=i1.doubleValueOf();
//输出结果:10.00

2.2 包装类型的自动拆装箱

包装类的装箱和拆箱解决了将基本类型封装到类之中的问题,但是如果要进行基本类型的运算,需要来回装箱和拆箱,代码编写麻烦,因此,Java在编译阶段引入自动拆装箱,能达到使用包装类和使用基本类型一样,语法没有区别。

int a=10;
int ret=a+1;
System.out.println(ret+1);
//包装类自动装箱
Integer i1=10;
//自动拆箱
Integer ret1=i1+1;
System.out.println(ret1+1);

2.3 包装类和基本类型的选取

由于包装类的自动拆装箱导致包装类和基本类型的使用没有区别。
阿里编码规约:
对于基本的POJO类(自定义类),类中的成员变量统一使用包装类,方法中局部变量可以使用基本类型。
举例说明:
包装类本质是类,默认值为null;基本类型的默认值为各个类型的默认值。
以银行账户为例:
如果查找开户成功但是未使用的用户时,对于成员变量salary的定义,如果是包装类则默认值为null;如果是基本类型,则为0.0,此时0.0也有可能会代表已经使用过银行卡只是存款数据为0。

2.4 包装类的缓存问题

包装类仍然是类对象,比较属性值是否相等,需要用equals方法。

Integer i1=120;
Integer i2=120;
System.out.println(i1==i2);
//输出结果为true
//超出最大值
Integer i3=130;
Integer i4=130;
System.out.println(i3==i4);
//输出结果为false

数值型包装类都会在内部有缓存池。
以Integer为例,默认缓存-128~127的数值,当第一次装箱时,该数值在缓存池中没有新对象,产生该对象置入缓存池;若下一次又有了该数值装箱,不会产生新的包装类对象,直接将缓存对象返回。因此会有时而true时而false的现象。
因此,对于包装类对象的属性比较问题,统一使用equals方法!

池化技术:复用已有对象、高效进行读取、不用反复进行创建和销毁对象

你可能感兴趣的:(java,java,jvm,开发语言)