1.Object类
1.1 概念
Object是Java默认提供的一个类。Java里面除了Object类,所有的类都是存在继承关系的。默认会继承Object父类。即所有类的对象都可以使用Object的引用进行接收。
//Person.java
public class Person {
}
//Student.java
public class Student {
}
//Test.java
public class Test {
public static void fun1(Object object){
System.out.println(object);
}
public static void fun2(Object object){
System.out.println(object);
}
public static void main(String[] args) {
fun1(new Person());
fun2(new Student());
}
}
所以在开发之中,Object类是参数的最高统一类型。但是Object类也存在有定义好的一些方法。如下:
以下就介绍几个常见的方法:
1.2 获取对象信息
如果要打印对象中的内容,可以直接重写Object类中的toString()方法
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
在类中自动生成toString()方法步骤如下:
1.3 对象比较equals方法
在Java中== 进行比较时:
1.如果== 左右两侧是基本类型变量,比较的是变量中值是否相同
2.如果==左右两侧是引用类型变量,比较的是引用变量地址是否相同
3.如果要比较对象中内容,必须重写Object中的equals方法,因为equals方法默认也是按照地址比较的:
等价于(地址的比较,因为那个对象调用了equal,this就是该对象的地址),这样是无效比较,我们需要对equal()方法进行重写
public boolean equals(Object obj) {
return (this == obj);
}
重写后的equal(方法:
@Overrid
public boolean equals(Object o) {//person2 向上提升了
Person tmp=(Person) o;
//由于person2 向上提升了
// 无法直接通过父类调用子类成员变量,首先需要强制类型转换为Person类
if(this.age==((Person) o).age&&this.name==((Person) o).name){
//我们认为年龄和名字相同则为相等
return true;
}else {
return false;
}
}
1.4 hashcode方法
public native int hashCode();
该方法是一个native方法,底层是由C/C++代码写的。我们看不到。
我们认为两个名字相同,年龄相同的对象,将存储在同一个位置,如果不重写hashcode()方法,我们可以来看示例
代码:
class Person {
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
public class TestDemo4 {
public static void main(String[] args) {
Person per1 = new Person("鱼嘟嘟", 20) ;
Person per2 = new Person("鱼嘟嘟", 20) ;
System.out.println(per1.hashCode());
System.out.println(per2.hashCode());
}
}
没有重写hashCode时我们发现:两个对象的hash值不一样
现在我们对hashCode()方法进行重写:
我们发现此时哈希值一样。
结论:
1、hashcode方法用来确定对象在内存中存储的位置是否相同
2、事实上hashCode() 在散列表中才有用,在其它情况下没用。在散列表中hashCode() 的作用是获取对象的散列码,进而确定该对象在散列表中的位置。
2.内部类
在外部类中,内部类定义位置与外部类成员所处的位置相同,因此称为成员内部类。
2.1 实例内部类
未被static修饰的成员内部类称为实例内部类
//Outclass.java
public class Outclass {
public int data1=1;
private int data2=2;
int data3=3;
void fun(){
int data4=4;
}
class Innerclass{
int data5=5;
}
}
//Test.java
public class Test {
public static void main(String[] args) {
//第一种实例方式
Outclass outclass=new Outclass();
Outclass.Innerclass innerclass1=outclass.new Innerclass();
System.out.println(innerclass1.data5);
//第二章实例方式
Outclass.Innerclass innerclass2=new Outclass().new Innerclass();
System.out.println(innerclass1.data5);
}
}
【注意事项】
- 外部类中的任何成员都可以在实例内部类方法中直接访问
- 实例内部类所处的位置与外部类成员位置相同,因此也受public、private等访问限定符的约束
- 在实例内部类方法中访问同名的成员时,优先访问自己的,如果要访问外部类同名的成员,必须:外部类名称.this.同名成员 来访问
- 实例内部类对象必须在先有外部类对象前提下才能创建
- 实例内部类的非静态方法中包含了一个指向外部类对象的引用
- 外部类中,不能直接访问实例内部类中的成员,如果要访问必须先要创建内部类的对象。
2.2 静态内部类
被static修饰的内部成员类称为静态内部类。
//Outclass.java
public class Outclass {
public int data1=1;
private int data2=2;
int data3=3;
void fun(){
int data4=4;
}
static class Innerclass{
static int data5=5;
}
}
//Test.java
public class Test {
public static void main(String[] args) {
System.out.println(Outclass.Innerclass.data5);
}
}
【注意事项】:
- 在静态内部类中只能访问外部类中的静态成员如果确实想访问,我们该如何做?
- 创建静态内部类对象时,不需要先创建外部类对象
2.3 局部内部类
定义在外部类的方法体或者{}中,该种内部类只能在其定义的位置使用,一般使用的非常少,此处简单了解下语法格式。
【注意事项】:
- 局部内部类只能在所定义的方法体内部使用
- 不能被public、static等修饰符修饰
- 编译器也有自己独立的字节码文件,命名格式:外部类名字$数字内部类名字.class
- 几乎不会使用
2.4 匿名内部类
后续介绍》》》 敬请期待!!