话接上回,继续核心类与API的学习,最后介绍一下Object类以及与数学、日期/时间有关的类,就结束该部分的学习了,其他的根据需要自行了解。

一、Object类

1、概述

Object 是 Java 类库中的一个特殊类,也是所有类的父类,任何 Java 对象都可以调用 Object 类的方法。Java 允许把任何类型的对象赋给 Object 类型的变量。当一个类被定义后,如果没有指定继承的父类,那么默认父类就是 Object 类。(向上和向下转型问题,在讲面向对象的继承特性那里讲过,不熟悉的可回去了解)

注:所有的对象都可以向 Object 进行转换,包含数组和接口类型,即一切的引用数据类型都可以使用 Object 进行接收

2、Object类常用方法

2.1 toString()方法(常用)

返回该对象的字符串,当程序输出一个对象或把某个对象和字符串进行连接运算时,系统会自动调用该对象的 toString() 方法返回该对象的字符串表示。案例如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
//加上toString()变灰系统提示不必要,说明对象输出时一定会调用Object类的toString()方法打印内容。
public class Demo {
public static void main(String[] args){
Demo d=new Demo();
System.out.println(d); //Demo@15db9742,不加toString()输出
System.out.println(d.toString()); //Demo@15db9742,加上toString()输出
}
}

//重写Object类的toString()方法,通过调用被子类重写过的toString()方法获取对象的一些信息
class Person { // 定义一个测试类person
private String name; // 封装私有化成员变量
private int age;
public Person(String name, int age){ // 带全部参数的构造方法(与类同名)
this.name=name; //this指向当前实例对象属性
this.age=age;
}
public String toString(){ // 重写父类(Object类)toString()方法,方法名和父类保持相同。(相同签名)
return "姓名:"+this.name+" 年龄:"+this.age;
}
public static void main(String[] args){
Person p=new Person("zhangsan",20); // 实例化Person对象
System.out.println(p.toString()); // 调用toString方法,可不写。
// 子类默认调用Object类的toString()方法,重写后调用重写的toString()方法
}
}

运行Person测试类,结果为

1
姓名:zhangsan 年龄:20

2.2 equals()方法

比较两个字符串的==内容是否相等==。注意与”==”区别。

“==”:比较的是 ==引用的变量地址是否相等==(即比较两个引用变量是否指向同一个实例 (在String类中讲过),通常字符串的比较只是关心内容是否相等。

案例:实现用户登录的验证功能,用户名密码都为admin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
import java.util.Scanner;  //导包
public class AdminDemo {
public static boolean Login(String name,String pwd) {
boolean con; //初始化
if (name.equals("admin") && pwd.equals("admin")) { //同时满足
con = true;
} else {
con = false;
}
return con;
}
public static void main(String[] args){
Scanner sc=new Scanner(System.in); //获取用户输入
System.out.println("------欢迎使用就业服务管理平台------");
System.out.println("用户名:");
String name= sc.next();
System.out.println("密码:");
String pwd= sc.next();
boolean con=Login(name,pwd); //调用Login()方法
if(con){ //登录结果
System.out.println("登录成功!");
}
else{
System.out.println("用户名或密码有误!");
}
}
}

运行结果

1
2
3
4
5
6
------欢迎使用就业服务管理平台------
用户名:
admin
密码:
amdin
用户名或密码有误!

2.3 getClass()方法

返回对象所属的类,是一个 Class 对象。通过 Class 对象可以获取该类的各种信息,包括类名、父类以及它所实现接口的名字等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 //对String类型调用getClass()方法,并输出其父类及实现的接口信息
public class Test02 {
public static void printClassInfo(Object obj) {
System.out.println("类名:" + obj.getClass().getName()); // 获取类名
System.out.println("父类:" + obj.getClass().getSuperclass().getName()); // 获取父类名
System.out.println("实现的接口有:"); // 获取实现的接口并输出
for (int i = 0; i < obj.getClass().getInterfaces().length; i++) {
System.out.println(obj.getClass().getInterfaces()[i]);
}
}
public static void main(String[] args) {
String strObj = new String();
printClassInfo(strObj);
}
}

运行结果

1
2
3
4
5
6
类名:java.lang.String
父类:java.lang.Object
实现的接口有:
interface java.io.Serializable
interface java.lang.Comparable
interface java.lang.CharSequence

2.4 clone()方法

创建并返回一个对象的拷贝(浅拷贝,对象内属性引用的对象==只拷贝引用地址==,而不会将引用的对象重新分配内存,而==深拷贝则会连引用的对象也重新创建==)

注:由于 Object 本身没有实现 Cloneable 接口,所以不重写 clone 方法并进行调用的话会发生CloneNotSupportedException 异常。(面试题拓展:浅拷贝与深拷贝的底层实现机制,有兴趣的自行了解)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class CloneDemo implements Cloneable{ //创建一个Cloneable接口的实现类
String name; //声明变量
int age;
public static void main(String[] args) throws CloneNotSupportedException { //抛出异常
CloneDemo cl=new CloneDemo(); //创建对象
cl.name="zhangsan"; //初始化变量
cl.age=21;
System.out.println(cl.name);
System.out.println(cl.age);
CloneDemo cl1=(CloneDemo)cl.clone(); //创建cl的拷贝
System.out.println(cl1.name); //打印结果
System.out.println(cl1.age);
}
}

运行结果

1
2
3
4
zhangsan
21
zhangsan
21

2.5 hashcode()方法

返回对象哈希值,是一个整数,表示在哈希表中的位置。
1)案例1

1
2
3
4
5
6
7
8
9
10
11
public class HashCodeDemo {//Object类是所有类的父类,默认继承Object类
public static void main(String[] args){
// Object使用hashCode()
Object obj1 = new Object();//子类可以调用Object类的任何方法,如hashCode()方法
System.out.println(obj1.hashCode()); //985922955
Object obj2 = new Object();
System.out.println(obj2.hashCode()); //1435804085
Object obj3 = new Object();
System.out.println(obj3.hashCode()); //1784662007
}
}

2)案例2

1
2
3
4
5
6
7
8
9
10
//String和ArrayList类都继承了Object,可以直接使用 hashCode()方法
import java.util.ArrayList; //导包
public class HashCodeDemo {//Object类是所有类的父类,默认继承Object类
public static void main(String[] args){
String s=new String();//创建String对象
System.out.println(s.hashCode()); //0,String调用hashCode()
ArrayList<Integer> list=new ArrayList<>();//1,创建ArrayList对象
System.out.println(list.hashCode()); //ArrayList调用hashCode()
}
}

3)案例3

1
2
3
4
5
6
7
8
9
10
//两个对象相等,哈希值也相等
public class HashCodeDemo {//Object类是所有类的父类,默认继承Object类
public static void main(String[] args){
Object obj1 = new Object();
Object obj2 = obj1; // obj1赋值给obj2(引用复制,指向同一个对象)
System.out.println(obj1.equals(obj2)); // true
System.out.println(obj1.hashCode()); // 985922955
System.out.println(obj2.hashCode()); // 985922955
}
}

二、与数学相关(了解)

1、Number & Math类

1.1 概述

Math类提供了大量的静态方法,用来进行数学计算。基本数学运算,如初等指数、对数、平方根和三角函数等,随机数(都是类方法)。

所有的包装类(Integer、Long、Byte、Double、Float、Short)都是抽象类 Number 的子类。

1.2 常用方法

比较简单,不一一列举,简单看几个,其他的自行了解。

1
2
3
4
5
6
7
parseInt():将字符串解析为int类型。
ceil():返回 >= 给定参数的的最小整数,类型为双精度浮点型。
floor():返回<=给定参数的最大整数 。
rint():返回与参数最接近的整数。类型为double
round():四舍五入。
random():返回带正号的 double 值(伪随机数),范围[0.0, 1.0)。
常量:double pi = Math.PI; // 3.14159...,double e = Math.E; // 2.7182818...

三、与日期/时间相关

主要介绍一下Date类和Calendar类,==Date 类封装了系统的日期和时间信息,Calendar 类则根据系统的日历来解释 Date 对象==。

1、Date类

表示系统特定的时间戳,可以精确到毫秒。

1.1 Date类构造方法

1)Date():获取本地的当前时间。(无参构造方法)
2)Date(long date):表示从 GMT(格林尼治时间)1970 年 1 月 1 日 0 时 0 分 0 秒开始经过参数 date 指定的毫秒数。(long类型参数的构造方法)

1.2 案例

案例1

1
2
3
4
5
6
7
8
9
import java.util.Date; //导包
public class DateDemo {
public static void main(String[] args){
Date date1=new Date(); // 调用无参数构造函数
System.out.println(date1); // Sun Jan 15 10:12:59 CST 2023
Date date2=new Date(60000);// 调用含有一个long类型参数的构造函数
System.out.println(date2); // Thu Jan 01 08:01:00 CST 1970
}
}

案例2
某一天特定时间要去做一件事,而且那个时间已经过去一分钟之后才想起来这件事还没有办,这时系统将会提示已经过去了多长时间。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
import java.util.Date; //导包
import java.util.Scanner;
public class DateDemo {
public static void main(String[] args){
Scanner input = new Scanner(System.in);
System.out.println("请输入要做的事情:");
String title = input.next();
Date date1 = new Date(); // 获取当前日期
System.out.println("[" + title + "] 这件事发生时间为:" + date1);
try {
Thread.sleep(60000);// 暂停 1 分钟
} catch (InterruptedException e) {
e.printStackTrace();
}
Date date2 = new Date();
System.out.println("现在时间为:" + date2);
if (date2.before(date1)) {
System.out.println("你还有 " + (date2.getTime() - date1.getTime()) / 1000 + " 秒需要去完成【" + title + "】这件事!");
} else {
System.out.println("【" + title + "】事情已经过去了 " + (date2.getTime() - date1.getTime()) / 1000 + " 秒");//毫秒转化为秒
}
}
}

结果

1
2
3
4
做饭
[做饭] 这件事发生时间为:Sun Jan 15 10:20:09 CST 2023
现在时间为:Sun Jan 15 10:21:09 CST 2023
【做饭】事情已经过去了 60

2、Calendar类

抽象类,为特定瞬间与 YEAR、MONTH、DAY_OF—MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(如获得下星期的日期) 提供了一些方法。

注:创建 Calendar 对象不能用 new 关键字,因为 Calendar类是一个抽象类,但是它提供了一个 getInstance() 方法来获得 Calendar类的对象。getInstance()方法之前也提过,用来返回一个类的唯一实例,其往往是static的,常见于单例模式的类中。

直接来看一个打印日历的小案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
//演示日历
import java.util.Calendar; //导包
import java.util.Date;
public class DateDemo {
public static void main(String[] args){
Date date=new Date();
System.out.println("当前时间为:"+date); //获取当前时间
Calendar calendar = Calendar.getInstance();
calendar.set(2023, 0, 15); // 实际的calendar对象所表示的日期为2023年1月15日
// 判断2023年1月15日为一周中的第几天
int index = calendar.get(Calendar.DAY_OF_WEEK) - 1;
char[] title = { '日', '一', '二', '三', '四', '五', '六' }; // 存放曰历的头部
int daysArray[][] = new int[6][7];// 存放日历的数据
int daysInMonth = 31; // 该月的天数
int day = 1; // 自动增长
for (int i = index; i < 7; i++) {
// 填充第一周的日期数据,即日历中的第一行
daysArray[0][i] = day++;
}
for (int i = 1; i < 6; i++) {
// 填充其他周的日历数据,控制行
for (int j = 0; j < 7; j++) {
// 如果当前day表示的是本月最后一天,则停止向数组中继续赋值
if (day > daysInMonth) {
i = 6;
break;
}
daysArray[i][j] = day++;
}
}
System.out.println("------------------2023 年 1 月--------------------\n");
for (int i = 0; i < title.length; i++) {
System.out.print(title[i] + "\t");
}
System.out.print("\n");
// 输出二元数组daysArray中的元素
for (int i = 0; i < 6; i++) {
for (int j = 0; j < 7; j++) {
if (daysArray[i][j] == 0) {
if (i != 0) {
// 如果到月末,则完成显示日历的任务,停止该方法的执行
return;
}
System.out.print("\t");
continue;
}
System.out.print(daysArray[i][j] + "\t");
}
System.out.print("\n");
}
}
}

运行结果

1
2
3
4
5
6
7
8
9
当前时间为:Sun Jan 15 10:48:12 CST 2023
------------------20231 月--------------------

日 一 二 三 四 五 六
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30 31