1.对象是数据和行为的基础
举例:
public Class Cat{
//数据
String name
//行为
private void meow(){
print('喵')
}
}
- 一切使用new运算符创造出来的都是对象
new Cat()
new Integer()
对象是由什么组成的?
- 所有的对象都在堆上分配
- 创建对象时发生的一切
public Class Home{
Cat cat
public Home(Cat cat){
this.cat = cat
}
public static void main(String[] args){
new Home(new Cat(age: 1, name: "咪咪")
}
}
public Class Cat{
int age
String name
private void meow(){
print('喵')
}
}
在执行完
new Home(new Cat(age: 1, name: "咪咪")
这句语句之后,内存发生了以下变化:
首先在堆中会创建一个新的Home类对象,其中存放Cat类的地址(reference),然后这个reference指向真正的Cat类对象,在Cat类对象中存放了4个字节的age, 和指向String的地址。
三步新建对象
1.在堆上分配空间
2.执行必要的初始化工作
原生类型会被初始化为0
引用类型会被初始化为null
3.执行构造器函数
方法的重载overload
啥是重载?
在类中写多个重名的方法,但是参数表不一样,例如下面的printName方法
public class Cat{
//方法
void printName(){}
void printName(String name){
}
public static void main(String[] args){
Cat cat = new Cat();
cat.printName();
}
}
如何区分同名的不同重载方法?
- 根据传递参数的类型区分
如果调用时 是cat.printName() 则调用第一个方法
如果调用时 是cat.printName("喵喵") 则调用第二个方法
2.但是根据类型区分重载方法,可能会存在一些坑
在Java中,int 和Integer是可以自动转换的
所以说,如果一个方法的调用可以匹配多个方法的声明,应该调用哪个方法呢?
例如 调用Cat.f(2)
传入的2是int类型
而int可以装箱成Integer,而integer又可以转换成Number,那么Java会如何选择?
答案是 最匹配的方法会被调用
那么如果两个重载方法匹配的程度相同呢?
编译器会报错,必须强制为参数指定类型
举例:
public class Cat{
public static void main(String[] args){
Cat cat = new Cat();
cat.f(null);
}
void f(Integer i){}
void f(ArrayList i){}
}
这里null 会同时匹配Integer和ArrayList
可以给方法设定默认值吗?
我的目标是在调用Cat.meow()方法时,即使不传递name参数,也能自动打印出默认值。
但是这在Java中不可以的,但是可以用重载曲线救国
public class Cat{
public static void main(String[] args){
Cat cat = new Cat();
cat.meow();
cat.meow("喵喵喵");
}
public void meow(){
meow("猫的默认名字");
}
public void meow(String value){
System.out.println(value);
}
}
重载meow()函数,并在其中调用meow(String name) 即可实现
构造器的重载
普通的方法可以初始化,那么构造器可以重载吗?
可以!
需要使用this()
public class Cat{
int age;
String name;
//创建一只默认的猫,1岁,名为嘻嘻嘻嘻
Cat(){
this("嘻嘻嘻嘻");
}
//创建一只默认的猫,1岁,名为name
Cat(String name){
this(20, name);
}
//创建一只指定了age, name的猫
Cat(int age, String name){
this.age = age;
this.name = name;
}
public static void main(String[] args) {
new Cat();
}
}
在调用时,会先调用Cat() --> Cat(Name) --> Cat(age, name)
对象初始化的顺序
1.静态成员的初始化
2.静态初始化块
3.成员的初始化
4.初始化块
初始化块就是{}包含的内容
public class Cat{
int age;
String name;
//初始化块
{
for(int i = 0; i < 100; i++){
age += 1;
}
}
//初始化块结束
Cat(int age, String name){
this.age = age;
this.name = name;
}
public static void main(String[] args) {
new Cat(2,"ASX");
}
}
对象的生命周期
1.如果一直新建对象,内存会不会爆炸?
可能不会
2.对象的内存如何被回收?
JVM中的garbage collection会回收
3.JVM怎么知道哪个对象没有被用到?
通过引用链(GC Roots)
JVM沿着GC root可以达到的数据都是有用的,其余的都是垃圾,会被回收
其中最关键的GC Root就是方法栈中的变量的引用链