JavaSE常用API之Object

Object类

所有类最终继承于Object,Object类也提供给我们很多便捷的方法,但是当我们的业务需求,Object提供的方法无法满足时,这个时候就需要重写Object方法了
常用方法有 :

  • String toString() 格式化对象为字符串形式
  • boolean equals() 比较两个对象的内容是否相同.
  1. 重写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方法配合连用,提升访问权限

  1. 重写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包。

  1. 八大包装类:
    • Integer
    • Character
    • 剩下的都是基本类型首字母大写,比如Long、Double等

注意:Boolean 和 Character 包装类继承于Object,数值包装类继承于Number;

  1. 包装与拆包:

代码示例:

//包装类  一般 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);
    
    }
    
}
  1. 自动包装与自动拆包:

代码示例:

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;
    }
    
}

你可能感兴趣的:(JavaSE常用API之Object)