Java基础语法易错知识点总结1-3

Java基础语法易错知识点总结1-3


一、对象创建时的内存细节

1.复制还是类似指针?

先看下面的代码,思考结果。

public class Test {

    public static void main(String[] args) {
        Book b1 = new Book();  
        b1.name = "金苹果";
        b1.info = "讲述了果农种植金色苹果的辛勤路程。";
        b1.say();

        Book b2 = b1;  //易错点
        b2.name = "银苹果";
        b1.say();
    }
}

class Book {
    String name;
    String info;

    void say(){
        System.out.println("书名:"+name+",简介:"+info);
    }

}

结果如下:
在这里插入图片描述
结果是否和你预期的一样呢,其实关键在于作者加了注释的那一行代码,很多人容易把它理解成复制。但其实不是,b1和b2都只是名称而已,他们指向的是同一个对象,用b2把name修改之后再用b1执行say()的时候输出的是银苹果而不是金苹果。

2.栈、堆和方法区

接下来结合变量名和对象在内存中的存储形式来理解上面的代码。如下图所示:在执行到Book b1系统会将Book类加载到方法区中,同时将Book b1变量存入栈中,在执行到new Book()时系统会将创建的Book对象存储到堆内存中,栈中的b1存放的是Book对象的地址,类似于c语言中的指针。当执行b1.name = "xxxx"和b1.info="xxxx"时系统会根据b1指向的地址去寻找堆中的对象进行修改。当执行Book b2 = b1时只不过是将b1指向的地址赋值给b2而已,所以b1和b2指向的是同一个地址,到这里就能理解上面的执行结果了。当执行b1.say()时系统会调用方法区中的say()方法,执行结束以后栈中的变量依次出栈,由GC线程回收内存中的垃圾。
在这里插入图片描述

3.测试

下面的代码请大家自己分析
在这里插入图片描述

二、方法的重载和重写

1.重载的条件

1.方法名称相同 ;
2.参数列表的长度或顺序或类型不同;
注意:是否构成重载和返回值类型无关!!!!!

2.重写

(1)子类实例化
子类Student实例化的时候会先创建父类Person的实例,由super关键字指向父类。super可以访问父类的构造方法、方法和属性。用this和super调用其他构造方法必须放在第一行。
在这里插入图片描述
(2)重写
1.参数列表、返回值和函数名与被重写方法相同
2.访问权限不能比被重写方法低
3.static和private不能重写,但是能够被再次声明

三、static静态关键字

1.静态修饰的属性

试想如果内存空间的存储情况如下,四个人的地区都是相同的,如果要对地区进行修改需要对4个人依次修改,这个过程十分繁琐,有没有什么简单的方法呢?
在这里插入图片描述
其实很简单,只需要用static修饰region就可以了,用static修饰的属性是在类创建的时候就被加载到方法区中了,所有对象指向的方法区中的同一个region。
在这里插入图片描述

2.静态修饰的方法

静态修饰的方法可以直接用类名来使用。
需要注意的是,静态资源是在类创建时创建的,而非静态资源是在对象创建时创建的。所以静态资源不能访问非静态资源,而非静态资源可以访问静态资源。

3.对main方法的理解

args数组其实是我们在运行main函数时可以传递进去的一些参数
在这里插入图片描述

四、权限修饰符

在这里插入图片描述

五、final关键字

可以修饰属性、变量、类、方法
修饰属性、变量:变成常量,无法再次赋值,如果局部变量之前没有赋值,那么可以赋值一次;属性用final修饰必须赋值,因为属性是有默认值的,不赋值系统认为操作无意义。
修饰类:不可继承
修饰方法:不可重写

全局常量:public static final,由一个或多个单词组成,单词之间用下划线隔开,所有字母前部大写。
eg: MAX_NUMBER

六、抽象类常见的问题

(1)抽象类不能实例化
(2)抽象类不能用final声明
(3)抽象类有构造方法,不能被用户创建,但是能被Java虚拟机创建
(4)必须使用public或protected修饰,因为priavte无法被继承,默认缺省为public

七、接口

(1)一个类可以实现多个接口
(2)接口之间可以多继承、
(3)接口的属性默认为public static final
(4)接口的方法默认为public abstract

八、多态

父类的引用指向子类的对象

九、代码块

(1)普通代码块
(2)构造代码块
随着每次对象的创建执行一次,且执行在构造方法之前。构造方法不一定会执行,但是构造代码块一定会执行。
(3) 静态代码块,其实就是在构造代码块的前面加上static
随着类的加载而执行,只执行一次
执行顺序:静态代码块>构造代码块>构造方法

十、内部类

(1)成员内部类
成员内部类可以无条件访问外部类的所有属性和方法,包括priavte和static
在这里插入图片描述

(2)局部内部类
在这里插入图片描述

(3)匿名内部类
属于局部内部类的一种
1.必须有父类或者接口,但二者不可兼得,同时也只能实现一个类或一个接口;
2.不能定义构造函数
3.不能存在任何静态成员变量和成员方法
4.不能是抽象的
5.所有的局部内部类只能访问final型的局部变量
在这里插入图片描述

(4)静态内部类
就是成员内部类加上static,唯一的不同就是使用内部类前可以不用创建外部内的实例,直接使用类名即可

十一、异常处理

1.异常体系结构

分为受检异常和非受检异常(运行时异常,即RuntimeException)。一旦异常产生,JVM会产生对应的异常类的实例化对象
在这里插入图片描述

2.try-catch-finally

(1)无论是否发生异常,finally必然执行。思考一下下面这种情况finally会执行吗,答案是肯定的。虽然try中有return,代码运行到return的时候系统会进入准备结束的阶段,在这个阶段finally会执行。
在这里插入图片描述
(2)思考下面的代码结果是多少,答案为28
在这里插入图片描述
思考下面的代码,答案是10
在这里插入图片描述
看完上面2种代码,你的内心一定是,what fuck??? why??? Are you kidding me???
稍安勿燥,这是面试的时候很多人极易死在的地方,其实也很好理解。其实很好理解return a和return p中的a和p不是直接return原来的a和p,而是复制,那你可能又会问,那为什么都是复制结果却是相反的呢。因为a是非引用数据类型,而p是引用数据类型,前面已经用栈和堆分析过了,说到这里就应该好理解了。
(3)需要注意的是exit是退出虚拟机,此时finally不会执行
在这里插入图片描述

3.throws

4.throw

用的比较少,哪有人喜欢给自己挖坑的,直接if判断不香吗

5.自定义异常类

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值