Object类
所有类最终继承于Object,Object类也提供给我们很多便捷的方法,但是当我们的业务需求,Object提供的方法无法满足时,这个时候就需要重写Object方法了
常用方法有 :
- String toString() 格式化对象为字符串形式
- boolean equals() 比较两个对象的内容是否相同.
-
重写toString()
toString是对实例对象格式化成字符串的API,一般用于项目中输出对象实例的信息,可以清晰的看到对象的数据信息,以便调试。- 通常使用一个类的toString就应当重写这个方法
- 返回值是字符串类型,该字符串格式可根据实际开发的需求而定
- 原则上该字符串应该包含当前实例对象的属性信息
- 自己定义的类需要重写toString java定义的类不用重写
返回该对象的字符串表示。通常,toString 方法会返回一个“以文本方式表示”此对象的字符串。
结果应是一个简明但易于读懂的信息表达式。java建议所有子类都重写此方法。
代码示例:
public class toStringOverride {
public static void main(String[] args) {
//创建一个A类的对象实例
A a = new A();
//输出a的数据,用于调试
System.out.println(a);
}
}
class A{
/* 封装的属性 名称、年龄、地址 */
private String name;
private int age;
private String address;
/* 构造方法赋初值 */
public A(){
name = "张三";
age = 20;
address = "xxx市xxx区xxx府xxx号楼xxx室";
}
/* toString()方法,将对象的信息格式化成一个字符串,便于调试*/
@Override
public String toString() {
return "A [i=" + i + ", name=" + name + ", age=" + age + ", address=" + address + "]";
}
}
toString的好处在于,当我们想要看到对象的数据时,不需要再用对象名 点(.)了,而且在实际的开发项目中,对象的属性都是被封装起来的,不可被外界调用,通常和get和set方法配合连用,提升访问权限
-
重写equals()
- 对于引用类型变量而言,由于保存的是地址,所以 "==" 做值比较时,比较的是两个变量指向的是否为"同一个对象".
- 而equals比较的是两个对象的内容是否相同.
- java提供的类中很多都已经重写了equals方法, 比如String.
自己定义的类一般需要重写equals()方法
通常重写equals()方法时hashCode()一起重写,hashCode()现阶段不需要了解过多,以后深入解析
重写根据需要来定 需要对比哪些就比哪些
代码示例:
public class equalsOverride {
public static void main(String[] args) {
//实例 c1、c2、c3 3个对象实例
Cell c1 = new Cell(0, 4);
Cell c2 = new Cell(0, 4);
Cell c3 = new Cell(0, 5);
// == 比较
System.out.println(c1 == c2);//false
System.out.println(c1 == c3);//false
// equals 比较
System.out.println(c1.equals(c2)); //false
System.out.println(c1.equals(c3)); //false
}
}
class Cell{
int row;
int col;
public Cell(int row,int col){
super();
this.row = row;
this.col = col;
}
//重写Object提供的equals方法
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass()) //getClass():返回当前运行类
return false;
Cell other = (Cell) obj; //转型
if (col != other.col)
return false;
if (row != other.row)
return false;
return true;
}
//重写Object提供的hashCode()方法 通常重写equals方法时hashCode()一起重写
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + col;
result = prime * result + row;
return result;
}
//将对象格式化为字符串形式,便于调试
@Override
public String toString(){
return "Cell { row ="+ row + ",col=" + col + " }";
}
}
equals和hashCode()
重写的equal()里一般比较的比较全面比较复杂,但效率就比较低,而利用hashCode()进行对比,则只要生成一个hash值进行比较就可以了,效率很高。
但有时不同的对象生成的hashcode也会一样(生成hash值得公式可能存在的问题),所以hashCode()只能说是大部分时候可靠,并不是绝对可靠,
所以我们可以得出:
1. equal()相等的两个对象他们的hashCode()肯定相等,也就是用equal()对比是绝对可靠的。
2. hashCode()相等的两个对象他们的equal()不一定相等,也就是hashCode()不是绝对可靠的。
hash值得问题以后深入讲解(API2阶段),现阶段只需要知其然!!!
包装类 java.lang.Number
Java是一个面向对象的编程语言,但是Java中的八种基本数据类型却是不面向对象的,为了使用方便和解决这个不足,在设计类时为每个基本数据类型设计了一个对应的类进行代表,这样八种基本数据类型对应的类统称为包装类(Wrapper Class),包装类均位于java.lang包。
- 八大包装类:
- Integer
- Character
- 剩下的都是基本类型首字母大写,比如Long、Double等
注意:Boolean 和 Character 包装类继承于Object,数值包装类继承于Number;
- 包装与拆包:
代码示例:
//包装类 一般 Integer i1 = Integer.valueOf(a);来包装 基本类型 在1个字节中 用的是同一个对象
public class Packs {
/**
* 包装类
* 强制转换时候可能会发生溢出错误和精度丢失
* 转换成当前类型的方法是拆包装方法
* @param args
*/
public static void main(String[] args) {
//int基本类型变量
int i = 5;
//包装int
Integer n = new Integer(i);
//char基本类型变量
char c = 'A';
//包装char
Character ch = new Character(c);
//包装double
Double dx = new Double(5.0);
//包装boolean
Boolean bt = new Boolean(true);
//包装float
Float ft = new Float((float)5);
//包装long
Long lt = new Long((long)15);
//强制转换时可能会发生精度丢失
System.out.println(dx.intValue());
System.out.println(dx.floatValue());
System.out.println(dx.byteValue());
System.out.println(dx.doubleValue());
System.out.println(n.shortValue());
System.out.println(n.longValue());
System.out.println(dx.intValue());
System.out.println(n.doubleValue());
System.out.println(n.byteValue());
System.out.println(n.shortValue());
System.out.println(n.floatValue());
System.out.println(n.longValue());
//强制转换类型时,如果超出范围则会出现溢出错误
Integer ix = new Integer(400);
Byte b = ix.byteValue(); //byte : -128~127 超出范围出现溢出
System.out.println(b);
//转化成当前类型是做拆包装处理
Integer i2 = new Integer(500);
int m = i2.intValue();
System.out.println(m);
}
}
- 自动包装与自动拆包:
代码示例:
public class Unpack {
/**
* 自动包装 和 自动拆包
* 1. 原理为Java的编译器会在编译期间进行代码替换,利用API
* 方法完成装箱和拆箱
* 2. 好处是可以大大节省代码量,提高程序员开发效率
*
* 每个包装类都 MAX_VALUE(最大值) 和 MIN_VALUE(最小值)
* @param args
*/
public static void main(String[] args) {
Integer i=5; //自动包装 编译器自动完成的 == Integer i = new Integer(5);
int n = i; //自动拆包 编译器自动完成的 == int n = i.intValue();
Double d = Double.MAX_VALUE; // 自动包装 double的最大值
double dx = d; //自动拆包
Float f = 5.0f;
float fx = f;
Character ch = 'A';
char c = ch;
Boolean b = true;
boolean bt = b;
Short s = 127;
short sx = s;
Byte t = 1;
byte tx = t;
Long l = Long.MAX_VALUE; //long的最大值
long lx = l;
System.out.println(d);
/*
* 当一个引用类型变量值为null的时候,访问其属性或方法 会发生空指针异常
* 拆包会发生空指针异常!!!
* k ==> k.intValue();
*/
Integer k = null;
int m = k;
}
}