1.API(Application Programming Interface)
应用程序编程接口
2.Java API
就是Java提供给我们使用的类,,
我们不需要关心这些类是如何实现的,只需要学习这些类如何使用
3.Object类概述
类层次结构的根类
所有类都直接或者间接的继承自该类
hasCode 返回对象的哈希值,不同对象的哈希值是不同的;
不是对象的实际地址值,可以理解为逻辑地址值。
int i = obj.hashCode();
public class MyTest {
public static void main(String[] args) {
// JavaAPI Java给我们提供好的一些类,我们得学会使用他
// Object 是所有类的顶层父类,所有类都是直接或间接继承自他
// java.lang 此包下的类,可以不用导包
//创建Object类对象
Object obj = new Object();
//看下Object中的成员方法
// int hashCode () 返回该对象的哈希码值。不同对象的哈希码值,是不一样的。
// System.out.println(obj);
int i = obj.hashCode();
System.out.println(i);
Object obj2 = new Object();
int i1 = obj2.hashCode();
System.out.println(i1);
}
}
返回此 Object 的运行时类,获取该类的字节码文件对象;
Class> getClass () 返回该类的字节码文件对象
import java.io.ObjectOutputStream;
public class MyTest {
public static void main(String[] args) {
//Object 所有类的顶层父类
Object obj = new Object();
int i = obj.hashCode(); //不同对象的哈希值是不一样的
//Object.class---->字节码文件对象
Class aClass = obj.getClass(); //获取该类的字节码文件对象
String s = obj.toString(); //获取该对象的地址值的字符串形式
案例:
public class MyTest2 {
public static void main(String[] args) {
//Object.class 字节码文件加载进内存-----JVM就会为Object.class文件创建一个对象。
Object obj = new Object();
Class clazz = obj.getClass(); //Object.class---->字节码文件对象。
Object obj2 = new Object();
Class aClass = obj2.getClass();
Object obj3 = new Object();
Class aClass1 = obj3.getClass();
System.out.println(obj==obj2); //false
System.out.println(clazz==aClass);
System.out.println(aClass==aClass1);
}
}
获取该对象的地址值的字符串表现形式,这里注意是地址值;
案例一:
public class MyTest {
public static void main(String[] args) {
Object obj = new Object();
String s = obj.toString(); //获取该对象的地址值的字符串表现形式
System.out.println(s);
Object o = new Object();
System.out.println(o.toString());
//public String toString () {
// return this.getClass().getName() + "@" + Integer.toHexString(this.hashCode());
//}
}
}
案例二:
import java.net.SocketTimeoutException;
public class MyTest2 {
public static void main(String[] args) {
Student student = new Student();
int i = student.hashCode();
System.out.println(i);
Class extends Student> aClass = student.getClass();
System.out.println(aClass.getName());
System.out.println(student.toString());
System.out.println("--------------------------");
Student student1 = new Student("张三", 23);
//System.out.println(student1.getName());
//System.out.println(student1.getAge());
student1.show();
//一般情况下,我们自定义的类,都喜欢重写父类toString()方法,让他打印成员变量的值,当你根据你实际情况,可以打印其他任何内容
System.out.println(student1.toString());
//子类如果对父类的方法实现不满意,子类可以重写
}
}
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
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;
}
public void show(){
System.out.println(name+"==="+age);
}
@Override
public String toString() {
return "姓名:"+this.name+"==="+"年龄"+this.age;
}
}
案例三:
public class MyTest {
public static void main(String[] args) {
Teacher teacher = new Teacher("张三", 23);
System.out.println(teacher);
}
}
class Teacher{
private String name;
private int age;
public Teacher(String name, int age) {
this.name = name;
this.age = age;
}
//利用软件重写toString()方法 alt+insert 选toStirng()方法,就会重写
@Override
public String toString() {
return "Teacher{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
a:指示其他某个对象是否与此对象“相等”。
源代码:
public boolean equals(Object obj) {
return (this == obj);
}
b:默认情况下比较的是对象的引用是否相同。
c:由于比较对象的引用没有意义,一般建议重写该方法。一般用于比较成员变量的值是否相等
d:==和equals()的区别。(面试题)
==比较两个对象地址值是否相同;equals比较两个变量值是否相同;
案例一:
public class MyTest {
public static void main(String[] args) {
Object obj = new Object();
Object obj2 = new Object();
// boolean equals (Object obj) 判断两个对象的地址值是否相同
System.out.println(obj == obj2);
boolean b = obj.equals(obj2);
//public boolean equals (Object obj){
// return (this == obj);
//}
//System.out.println(b);
System.out.println("---------------------");
Student s1 = new Student("张三", 23);
Student s2 = new Student("张三", 23);
System.out.println(s1 == s2);//false
//System.out.println(s1.equals(s2)); //true
//我觉得,s1.equals(s2) 比较两个对象的地址值,是否相同,对我来说意义不大,我认为的是,只要两个对象的成员变量的值一样,我就认为这两个对象一样。那么我就得重写父类的equals()方法,让他去比较两个对象的成员变量的值是否相同
boolean b1 = s1.equals(new Teacher());//ClassCastException 类型转换异常
System.out.println(b1);
System.out.println("---------------");
boolean b2 = s1.equals(s1);
System.out.println(b2);
}
}
class Student {
private String name;
private int age;
public Student(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object obj) {
//如果是自己跟自己比,直接就是true
if (this == obj) {
return true;
}
// 让他去比较两个对象的成员变量的值是否相同
//我怎么判断这个obj 是Student类型的。
//A:
//关系运算符有哪些
// == ,!= , < , > , <= , >= , instanceof(后面讲解)
//instanceof 判断一个引用,是否是,该类型的一个引用
if (!(obj instanceof Student)) {
return false;
}
//向下转型
Student stu = (Student) obj;
//"张三"=="张三" 0x001==0x002
// this.name.equals(stu.name) 比较两个字符串的内容是否相同
//String extends Object{
// //字符串类,也认为父类的equals方法不满意,字符串这个类想要比较,连个字符串的内容是否相同
// 所以字符串也重写了父类的equals方法 去比较两个字符串的内容是否相同
// }
return this.name.equals(stu.name) && this.age == stu.age;
}
}
class Teacher {
}
案例二:
**
Object 类中的equals方法默认比较的是,两个对象的地址值是否相同,
那么很多类,都觉得这种比较方法意义不大,都会重写,按照自己的比较方式去比较
我们自定义的类,重写equals方法是比较两个对象的成员变量的值是否相同 **
public class MyTest {
public static void main(String[] args) {
/* Object 类中的equals方法默认比较的是,两个对象的地址值是否相同,
那么很多类,都觉得这种比较方法意义不大,都会重写,按照自己的比较方式去比较
我们自定义的类,重写equals方法是比较两个对象的成员变量的值是否相同
*/
System.out.println(new Student("张三", 23).equals(new Student("张三", 23)));
}
}
import java.util.Objects;
public class Student {
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
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 String toString() {
return "Student{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
//alt+insert
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Student student = (Student) o;
return age == student.age && Objects.equals(name, student.name);
}
@Override
public int hashCode() {
return Objects.hash(name, age);
}
}
clone()的权限修饰符是受保护的,在用的时候,让该类重写该方法,并把该方法的权限修饰符改为public
对象的浅克隆:浅克隆和深克隆
使用clone()方法采用的是浅克隆的方式
对象浅克隆要注意的细节:
** 如果一个对象需要调用clone的方法克隆,那么该对象所属的类必须要实现Cloneable接口。**
Cloneable接口只不过是一个标识接口而已,没有任何方法。
对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份。
对象的浅克隆也不会调用到构造方法的。
对象的深克隆(后面讲):采用IO流来实现 使用 ObjectOutputStream 将对象写入文件中,然后再用ObjectInputStream读取回来
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
// protected Object clone () 创建并返回此对象的一个副本。
Dog dog = new Dog();
System.out.println(dog);
dog.name="小黑";
dog.age=10;
System.out.println(dog.name);//小黑
System.out.println(dog.age);//10
// dog=new Dog();
Dog dog1= (Dog) dog.clone();
System.out.println(dog1);
System.out.println(dog1.name);//小白,小黑
System.out.println(dog1.age); //23 10
//CloneNotSupportedException 克隆不支持异常
Dog dog2 = new Dog();
Dog dog3 = (Dog) dog2.clone();
System.out.println(dog3.name);
System.out.println(dog3.age);
}
}
//此类实现了 Cloneable 接口,以指示 Object.clone()方法可以合法地对该类实例进行按字段复制。
//
// 如果在没有实现 Cloneable 接口的实例上调用 Object 的 clone 方法,则会导致抛出 CloneNotSupportedException 异常。
//Cloneable 没有任何抽象方法的接口,是一个标记接口
class Dog extends Object implements Cloneable{
String name="小白";
int age=23;
@Override
protected Object clone() throws CloneNotSupportedException {
//调用父类的clone功能
return super.clone();
}
}
案例二:
1.对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把另外一个对象也克隆一份 。
2.深克隆:克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象 克隆的时候不仅要克隆这个对象,还有克隆这个对象里面维护的那个对象 深克隆:可以通过序列化流来实现,后期学到IO流的时候讲
import java.io.ObjectOutputStream;
import java.util.zip.DeflaterOutputStream;
public class MyTest {
public static void main(String[] args) throws CloneNotSupportedException {
//克隆时注意两点:1.这个clone方法是一个受保护的方法,我们在使用时,需要子类重写一下,但是重写逻辑还是用父类的clone逻辑
//2.这个类必须实现一个Cloneable接口,这样克隆才会被支持
//Dog dog = new Dog();
//dog.name="旺财";
//dog.age=10;
//Dog dog1 = (Dog) dog.clone();
//dog1.name="小黑";
//dog1.age=19;
//System.out.println(dog.name);//
//System.out.println(dog.age);
//System.out.println(dog1.name);
//System.out.println(dog1.age);
System.out.println("---------------------");
DogFood dogFood = new DogFood("王中王");
Dog dog = new Dog("旺财", 3, dogFood);
dog.dogFood.name = "双汇";
Dog dog1 = (Dog) dog.clone();
dog1.dogFood.name = "金锣";
System.out.println(dog.dogFood.name);//
System.out.println(dog1.dogFood.name);//
new Object().hashCode();
//对象的浅克隆就是克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象,这时候只是克隆另外一个对象的地址,而没有把
//另外一个对象也克隆一份。
//深克隆:克隆一个对象的时候,如果被克隆的对象中维护了另外一个类的对象 克隆的时候不仅要克隆这个对象,还有克隆这个对象里面维护的那个对象 深克隆:可以通过序列化流来实现,后期学到IO流的时候讲
}
}
class Dog implements Cloneable {
public String name;
public int age;
public DogFood dogFood;
public Dog() {
}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
public Dog(String name, int age, DogFood dogFood) {
this.name = name;
this.age = age;
this.dogFood = dogFood;
}
}
class DogFood {
public String name;
public DogFood(String name) {
this.name = name;
}
}