Java基础(九):Object 类的使用

Java基础系列文章

Java基础(一):语言概述

Java基础(二):原码、反码、补码及进制之间的运算

Java基础(三):数据类型与进制

Java基础(四):逻辑运算符和位运算符

Java基础(六):数组

Java基础(七):面向对象编程

Java基础(八):封装、继承、多态性

Java基础(九):Object 类的使用


目录

  • 一、如何理解根父类
  • 二、Object类的方法
    • 1、(重点)equals()
    • 2、(重点)toString()
    • 3、clone()
    • 4、finalize()
    • 5、getClass()
  • 三、native关键字的理解


一、如何理解根父类

java.lang.Object是类层次结构的根类,即所有其它类的父类。每个类都使用 Object 作为超类

Java基础(九):Object 类的使用_第1张图片

  • 所有对象(包括数组)都实现这个类的方法
  • 如果一个类没有特别指定父类,那么默认则继承自Object类
  • 例如:
public class Person {
	...
}
//等价于:
public class Person extends Object {
	...
}

二、Object类的方法

1、(重点)equals()

= =

  • 基本类型比较值:只要两个变量的值相等,即为true
int a=5; 
if(a==6){…}
  • 引用类型比较引用(是否指向同一个对象):只有指向同一个对象时,==才返回true
Person p1=new Person();  	    
Person p2=new Person();
if (p1==p2){…}

equals()

  • 所有类都继承了Object,也就获得了equals()方法。还可以重写
  • 只能比较引用类型,Object类源码中equals()的作用与“==”相同:比较是否指向同一个对象

Java基础(九):Object 类的使用_第2张图片

  • 当用equals()方法进行比较时,对类File、String、Date及包装类(Wrapper Class)来说
    • 是比较类型及内容而不考虑引用的是否是同一个对象
    • 原因:在这些类中重写了Object类的equals()方法
  • 当自定义使用equals()时,可以重写。用于比较两个对象的“内容”是否都相等

练习

int it = 65;
float fl = 65.0f;
System.out.println(6565.0f是否相等?” + (it == fl)); // true

char ch1 = 'A'; char ch2 = 12;
System.out.println("65和'A'是否相等?" + (it == ch1)); // true
System.out.println("12和ch2是否相等?" + (12 == ch2)); // true

String str1 = new String("hello");
String str2 = new String("hello");
System.out.println("str1和str2是否相等?"+ (str1 == str2)); // false

System.out.println("str1是否equals str2?"+(str1.equals(str2))); // true

2、(重点)toString()

  • 默认情况下,toString()返回的是“对象的运行时类型 @ 对象的hashCode值的十六进制形式"
  • 在进行String与其它类型数据的连接操作时,自动调用toString()方法
Date now = new Date();
System.out.println(“now=+ now);  //相当于
System.out.println(“now=+ now.toString()); 
  • 如果我们直接System.out.println(对象),默认会自动调用这个对象的toString()
    • 因为Java的引用数据类型的变量中存储的实际上时对象的内存地址
    • 但是Java对程序员隐藏内存地址信息
    • 所以不能直接将内存地址显示出来
    • 所以当你打印对象时,JVM帮你调用了对象的toString()
  • 可以根据需要在用户自定义类型中重写toString()方法
    • 如String 类重写了toString()方法,返回字符串的值
s1="hello";
System.out.println(s1);//相当于System.out.println(s1.toString());

例如自定义的Person类:

public class Person {  
    private String name;
    private int age;

    @Override
    public String toString() {
        return "Person{" + "name='" + name + '\'' + ", age=" + age + '}';
    }
}

3、clone()

  • 实现了Cloneable接口的类
  • 可以通过.clone()方法克隆对象(赋值的属性及方法)
//Object类的clone()的使用
public class CloneTest {
	public static void main(String[] args) {
		Animal a1 = new Animal("花花");
		try {
			Animal a2 = (Animal) a1.clone();
			System.out.println("原始对象:" + a1);
			a2.setName("毛毛");
			System.out.println("clone之后的对象:" + a2);
		} catch (CloneNotSupportedException e) {
			e.printStackTrace();
		}
	}
}

class Animal implements Cloneable{
	private String name;

	public Animal() {
		super();
	}

	public Animal(String name) {
		super();
		this.name = name;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@Override
	public String toString() {
		return "Animal [name=" + name + "]";
	}
	
	@Override
	protected Object clone() throws CloneNotSupportedException {
		// TODO Auto-generated method stub
		return super.clone();
	}
	
}

4、finalize()

  • 当对象被回收时,系统自动调用该对象的 finalize() 方法。(不是垃圾回收器调用的,是本类对象调用的)
    • 永远不要主动调用某个对象的finalize方法,应该交给垃圾回收机制调用
  • 什么时候被回收?
    • 当某个对象没有任何引用时,JVM就认为这个对象是垃圾对象
    • 就会在之后不确定的时间使用垃圾回收机制来销毁该对象
    • 在销毁该对象前,会先调用 finalize()方法
  • 子类可以重写该方法,目的是在对象被清理之前执行必要的清理操作
    • 比如,在方法内断开相关连接资源
    • 如果重写该方法,让一个新的引用变量重新引用该对象,则会重新激活对象
  • 在JDK 9中此方法已经被标记为过时
public class FinalizeTest {
	public static void main(String[] args) {
		Person p = new Person("Peter", 12);
		System.out.println(p);
		p = null;//此时对象实体就是垃圾对象,等待被回收。但时间不确定。
		System.gc();//强制性释放空间
	}
}

class Person{
	private String name;
	private int age;

	public Person(String name, int age) {
		super();
		this.name = name;
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	//子类重写此方法,可在释放对象前进行某些操作
	@Override
	protected void finalize() throws Throwable {
		System.out.println("对象被释放--->" + this);
	}
	@Override
	public String toString() {
		return "Person [name=" + name + ", age=" + age + "]";
	}
	
}

5、getClass()

  • public final Class getClass():获取对象的运行时类型
  • 因为Java有多态现象,所以一个引用数据类型的变量的编译时类型与运行时类型可能不一致
  • 因此如果需要查看这个变量实际指向的对象的类型,需要用getClass()方法
public static void main(String[] args) {
	Object obj = new Person();
	System.out.println(obj.getClass());//运行时类型
}

结果:

class com.atguigu.java.Person

三、native关键字的理解

使用native关键字说明这个方法是原生函数,也就是这个方法是用C/C++等非Java语言实现的,并且被编译成了DLL,由Java去调用

  • 本地方法是有方法体的,用c语言编写。由于本地方法的方法体源码没有对我们开源,所以我们看不到方法体
  • 在Java中定义一个native方法时,并不提供实现体

1. 为什么要用native方法

  • Java使用起来非常方便,然而有些层次的任务用java实现起来不容易,或者我们对程序的效率很在意时
  • 例如:Java需要与一些底层操作系统或某些硬件交换信息时的情况
  • native方法正是这样一种交流机制:它为我们提供了一个非常简洁的接口,而且我们无需去了解Java应用之外的繁琐的细节

2. native声明的方法,对于调用者,可以当做和其他Java方法一样使用

  • native method的存在并不会对其他类调用这些本地方法产生任何影响
  • 实际上调用这些方法的其他类甚至不知道它所调用的是一个本地方法
  • JVM将控制调用本地方法的所有细节

你可能感兴趣的:(java基础,java,jvm,servlet)