API是(Application Programing Interface)应用程序编程接口的缩写。java API是java把JDK底层源码封闭好提供给我们使用的类,而且还有CHM后缀的JDK帮助文档,像查字字那样去查阅API使用说明。
1、Object类
java的根类,也叫超类,所有的直接或间接继承了Object类,所有的类都实现这个类的方法,所以自己新建的类可直接调用Object的方法(有的要声明使用接口,如Object类的clone()方法)。开发中主要用到它以下几个成员方法:
public int hashCode() :返回该对象的哈希码值(这值是根据对象地址值得到,却不是真的对象地址值,可理解为地址值)。
public final Class getClass() :返回此 Object 的运行时类
public String toString() :返回该对象的字符串表示。(通常重写)
public boolean equals(Object obj) :指示其他某个对象是否与此对象“相等”。(通常需重写)
protected void finalize() :当垃圾回收器确定不存在对该对象的更多引用时,由对象的垃圾回收器调用此方法。用于垃圾回收,但是什么时候回收不确定。(简单了解即可)
protected Object clone() :创建并返回此对象的一个副本,需要使用Cloneable 接口。
1.1、hashCode()和getClass()方法
实体类 测试类 class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String n) {
this.name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
this.age = a;
}
}
/*
public int hashCode():返回该对象的哈希码值(这值是根据对象地址值得到,却不是真的对象地址值,可理解为地址值)。
public final Class getClass():返回此 Object 的运行时类
*/
class TestDemo {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1 );
System.out.println(s1.hashCode() );
System.out.println(s1.getClass() );
// getName() 为Class类的方法:
//public String getName():以 String 的形式 返回此 Class 对象所表示的实体
System.out.println(s1.getClass().getName() );
}
}
//执行结果如下
test.Student@15db9742
366712642
class test.Student
test.Student
1.2、toString()方法
//在上面的测试类添加多一行打印s1.toString()方法
class TestDemo {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1);
System.out.println(s1.hashCode());
System.out.println(s1.getClass());
System.out.println(s1.getClass().getName());
System.out.println("---------------");
System.out.println(s1.toString() );
}
}
//执行结果如下
test.Student@15db9742
366712642
class test.Student
test.Student
---------------test.Student@15db9742
通过查jdk帮助文档说明,toString()返回该对象的字符串表示 。该toString类方法Object返回一个由其中的对象是一个实例,该符号字符`的类的名称的字符串@ ”和对象的哈希码的无符号的十六进制表示。 换句话说,这个方法返回一个等于下列值的字符串:
getClass().getName() + '@' + Integer.toHexString(hashCode())
//那么再来上面的代码又添加打印getClass().getName() + '@' + Integer.toHexString(hashCode())
class TestDemo {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(s1);
System.out.println(s1.hashCode());
System.out.println(s1.getClass());
System.out.println(s1.getClass().getName());
System.out.println("---------------");
System.out.println(s1.toString());
System.out.println("-------@-------");
System.out.println(s1.getClass().getName() + '@' + Integer.toHexString(s1.hashCode()) );
}
}
//执行结果如下
test.Student@15db9742
366712642
class test.Student
test.Student
---------------
test.Student@15db9742
-------@-------test.Student@15db9742
经上验证,toString()确定是经过一系列转换得到这一串“test.Student@15db9742 ”字符串,但是意义不大,故要进行toString()方法的重写,如下:
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String n) {
this.name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
this.age = a;
}
}
//重写toString()一般是把该类的所有成员变量值组成字符串返回即可 。
//而且强大的eclipse也有快捷键生成toString()方法,Shift + Alt + s 后再选“Generate toString().. ”即可自动生成
class Student {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String n) {
this.name = n;
}
public int getAge() {
return age;
}
public void setAge(int a) {
this.age = a;
}
@Override
public String toString() {
return "Student [name=" + name + ", age=" + age + "]";
}
}
1.3、equals()方法
public boolean equals(Object obj):指示其他某个对象是否与此对象“相等”。 这个方法,默认情况下比较的是地址值 。如下:
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(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;
}
}
/*
==和equals的区别?
== :
基本类型:比较的就是值是否相同
引用类型:比较的就是地址值是否相同
equals :
引用类型:默认情况下,比较的是地址值。
不过,我们可以根据情况自己重写该方法。一般重写都是自动生成,比较对象的成员变量值是否相同
*/
public class TestDemo {
public static void main(String[] args) {
Student s1 = new Student("林青霞", 27);
Student s2 = new Student("林青霞", 27);
System.out.println(s1 == s2); // false
Student s3 = s1;
System.out.println(s1 == s3);// true
System.out.println("---------------");
System.out.println(s1.equals(s2)); // obj = s2; //false
System.out.println(s1.equals(s1)); // true
System.out.println(s1.equals(s3)); // true
Student s4 = new Student("风清扬",30);
System.out.println(s1.equals(s4)); //false
}
}
因为比较地址值一般来说意义不大,所以我们要重写该方法。一般把equals()方法重写为比较两对象的成员变量值是否相同 。
//在实体类Student中进行equals()方法重写
public class Student {
private String name;
private int age;
public Student() {
super();
}
public Student(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
public boolean equals(Object obj) {
//为了提高效率,判断为同一对象即返回true if(this == obj){
return true;
}
//为了提供程序的健壮性
//这个时候,我们要判断的是对象是否是某个类的对象?
//记住一个格式:对象名 instanceof 类名
//表示:判断该对象名是否是该类名一个对象 if(!(obj instanceof Student)){
return false;
}
//如果是就继续 ,向下转型 Student s = (Student)obj;
return this.name.equals(s.name) && this.age == s.age;
//注意这里的this.name是指上面的 private String name,而String类的equals()方法, String的equals()方法是重写自Object类的,比较的是字符串的内容是否相同。 }
}
以上的Object类的equals()方法是手动重写的,也可以用eclipse自动生成重写的equals()方法,生成的方法如下:
//eclipse自动生成和手动重写的equals()方法效果一样
@Override
public boolean equals(Object obj) {
if (this == obj) //判断是否为同一对象
return true;
if (obj == null) //判断不为同一类的对象
return false;
if (getClass() != obj.getClass()) //判断不为同一类的对象
return false;
Student other = (Student) obj; // 除了上面三种情况外,是同一类的对象
if (age != other.age)
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
1.4、clone()方法
protected Object clone() :创建并返回此对象的一个副本,需要使用Cloneable 接口。
//实体类
public class Student implements Cloneable {
private String name;
private int age;
public Student() {
super();
}
public Student(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 Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
//测试类
/*
protected Object clone():创建并返回此对象的一个副本。
A:重写该方法
Cloneable:此类实现了 Cloneable 接口,以指示 Object.clone() 方法可以合法地对该类实例进行按字段复制。
这个接口是标记接口,告诉我们实现该接口的类就可以实现对象的复制了。
*/
public class TestDemo {
public static void main(String[] args) throws CloneNotSupportedException {
//创建学生对象
Student s = new Student();
s.setName("坂井泉水");
s.setAge(18);
//克隆学生对象
Object obj = s.clone();
Student s2 = (Student)obj;
System.out.println(s.getName()+"---"+s.getAge());
System.out.println(s2.getName()+"---"+s2.getAge());
//以前的做法
Student s3 = s;
System.out.println(s3.getName()+"---"+s3.getAge());
System.out.println("---------");
//其实是有区别的
s3.setName("王祖贤");
s3.setAge(20);
System.out.println(s.getName()+"---"+s.getAge());
System.out.println(s2.getName()+"---"+s2.getAge());
System.out.println(s3.getName()+"---"+s3.getAge());
}
}
//执行结果如下
坂井泉水---18
坂井泉水---18
坂井泉水---18
---------
王祖贤---20
坂井泉水---18
王祖贤---20
2、Scanner类
Scanner类常用于接收键盘录入数据,这个类是在util工具包里的。
2.1、Scanner(System.in)的构造方法
/*
* Scanner:用于接收键盘录入数据。
*
* 前面的时候:
* A:导包 import java.util.Scanner;
* B:创建对象 Scanner sc = new Scanner(System.in);
* C:调用方法 int x = sc.nextInt();
*
* System类下有一个静态的字段:
* public static final InputStream in ; 标准的输入流,对应着键盘录入。(查帮忙文档system的in)
*
* InputStream is = System.in;
*
* class Demo {
* public static final int x = 10;
* public static final Student s = new Student();
* }
* int y = Demo.x;
* Student s = Demo.s; //由这里赋值过程想到InputStream is = System.in;再想到下面system.in是用到 Scanner(InputStream source)的构造方法的
*
*
* 构造方法:
* Scanner(InputStream source)
*/
import java.util.Scanner;
public class TestDemo {
public static void main(String[] args) {
// 创建对象
Scanner sc = new Scanner(System.in);
System.out.print("请输入x的值: ");
int x = sc.nextInt();
System.out.println("x=" + x);
}
}
2.2、Scanner类的hasNextXxx()和 nextXxx()方法
import java.util.Scanner;
/*
* 基本格式:
* public boolean hasNextXxx():判断是否是某种类型的元素
* public Xxx nextXxx():获取该元素
*
* 举例:用int类型的方法举例
* public boolean hasNextInt()
* public int nextInt()
*/
public class TestDemo {
public static void main(String[] args) {
// 创建对象
Scanner sc = new Scanner(System.in);
System.out.print("请输入的int类型的值x: ");
// 获取数据
if (sc.hasNextInt()) {
int x = sc.nextInt();
System.out.println("x:" + x);
} else {
System.out.println("你输入的数据有误");
}
}
}
2.3、常见的Scanner获取数据出现的小问题
import java.util.Scanner;
/*
* 常用的两个方法:
* public int nextInt():获取一个int类型的值
* public String nextLine():获取一个String类型的值
*
* 出现问题了:
* 先获取一个数值,在获取一个字符串,会出现问题 (先输完数字后,下一个字符串不让输,直接就打印结果了)。
* 主要原因:就是那个换行符号的问题。
* 如何解决呢?
* A:先获取一个数值后,再创建一个新的键盘录入对象获取字符串。
* B:把所有的数据都先按照字符串获取,然后转换成你想要的类型。
*/
public class TestDemo {
public static void main(String[] args) {
// 创建对象
Scanner sc = new Scanner(System.in);
// 获取两个int类型的值
// int a = sc.nextInt();
// int b = sc.nextInt();
// System.out.println("a:" + a + ",b:" + b);
// System.out.println("-------------------");
// 获取两个String类型的值
// String s1 = sc.nextLine();
// String s2 = sc.nextLine();
// System.out.println("s1:" + s1 + ",s2:" + s2);
// System.out.println("-------------------");
// 先获取一个字符串,在获取一个int值
// String s1 = sc.nextLine();
// int b = sc.nextInt();
// System.out.println("s1:" + s1 + ",b:" + b);
// System.out.println("-------------------");
// 先获取一个int值,在获取一个字符串
// int a = sc.nextInt(); //问题处:输入数字后,回车/r操作被识别为字符处
//因为 Scanner也是一个简单的文本扫描器,可以使用正则表达式解析原始类型和字符串。
// String s2 = sc.nextLine();
// System.out.println("a:" + a + ",s2:" + s2);
// System.out.println("-------------------");
// A:先获取一个数值后,再创建一个新的键盘录入对象获取字符串。
// int a = sc.nextInt();
// Scanner sc2 = new Scanner(System.in);
// String s = sc2.nextLine();
// System.out.println("a:" + a + ",s:" + s);
// B:把所有的数据都先按照字符串获取,然后转换成你想要的类型。
int a = Integer.parseInt(sc.nextLine());
String s2 = sc.nextLine();
System.out.println("a:" + a + ",s2:" + s2);
System.out.println("-------------------");
}
}