- 数据类型
- 分类
- 基本类型数据创建
- 数组的创建
- 对象的创建
- 比较
- 长度
- i++,++i
- 抽象类和接口
- 相同点
- 不同点
- 成员变量与局部变量
- 重载(Overload)和重写(Override)
- final finally finalize区别
- IO流
- 异常
- 注解
- 反射
- 线程
四类八种基本数据类型
除掉这四类八种基本类型,其它的都是对象,也就是引用类型,包括数组。
方法体里声明的基本数据类型在栈内存里
数组的创建int[] arr1= new int{1,2,3,4,5};
int[] arr2 = arr1;
对于引用类型来说,赋值(=号)就相当于拷贝了一份内存地址
若修改arr[3] =8,则打印arr1[3]和arr2[3]的值,都是8,因为数组arr1和数组arr2指向同一块堆内存
Person per1= new Person(“张三”,21);
Person per2 = per1;
per1.setName(“李四”);
per1.setAge(35);
结果是false,true,true,
当==两边是基本数据类型时,==比较的是两边的值是否相等,
当==两边是引用类型时,比较的是两个内存地址,也可以看成是看这两个引用是否指向堆内存里的同一块地址
byte:-128~127,
计算机用补码表示,正数的反码和补码是本身,负数的反码是原码符号位不变,其他位取反,补码是反码+1.(第一位符号位,正数0,负数1)
正数最大值:01111111,2^8-1=127,
负数最小值:原码10000001,-1,取反为11111110,加1, 补码为11111111
原码11111111,-127,取反为10000000,加1, 补码为10000001
原码10000000,-0,取反为11111111,加1, 补码为10000000,把-0定义成-128
transient:修饰的变量不会被序列化
volatile:修饰的变量,每次获取都是最新值
JMM:
i++ 即后加加,原理是:先自增,然后返回自增之前的值
++i 即前加加,原理是:先自增,然后返回自增之后的值
一个变量也是表达式,多个表达式的加减法运算都是从左到右进行的
抽象类是用来捕捉子类的通用特性的,实现代码重用。接口是抽象方法的集合,利用接口可以达到 API 定义和实现分离的目的,提供程序的扩展性和可维护性。
从设计层面来说,抽象类是对类的抽象,是一种模板设计,接口是行为的抽象,是一种行为的规范。
接口和抽象类都不能实例化
都位于继承的顶端,用于被其他类实现或继承
都包含抽象方法,其子类都必须重写这些抽象方法
| 抽象类 | 接口 | |
|---|---|---|
| 声明 | abstract声明 | interface声明 |
| 实现 | 子类使用extends关键字来继承抽象类。如果一个类继承了抽象类,那么该子类必须实现抽象类的所有抽象方法。 | 子类使用implements关键字来实现接口。如果一个类实现了接口,那么该子类必须实现父接口的所有方法。 |
| 构造器 | 可以有构造器 | 不能有 |
| 修饰符 | 任意修饰符 | 默认public,不能未private或者protected |
| 继承 | 一个类最多只能继承一个抽象类 | 一个类可实现多接口 |
备注:Java8中接口中引入默认方法和静态方法,以此来减少抽象类和接口之间的差异。现在,我们可以为接口提供默认实现的方法了,并且不用强制子类来实现它。
接口和抽象类各有优缺点,在接口和抽象类的选择上,必须遵守下面的几个原则:
抽象类用来定义某个领域的固有属性,即抽象类表示它是什么,接口用来定义某个领域的扩展功能,即接口表示它能做什么。
当需要为子类提供公共的实现代码时,应优先考虑抽象类。因为抽象类中的非抽象方法可以被子类继承,使实现功能的代码更简洁。
当注重代码的扩展性和可维护性时,应当优先采用接口。①接口与实现类之间可以不存在任何层次关系,接口可以实现毫不相关类的行为,比抽象类的使用更加方便灵活;②接口只关心对象之间的交互方法,而不关心对象所对应的具体类。接口是程序之间的一个协议,比抽象类的使用更安全、清晰。一般使用接口的情况更多。
变量:在程序执行的过程中,其值可以在某个范围内发生改变的量。从本质上讲,变量其实是内存中的一小块区域
各变量联系与区别
成员变量:作用范围是整个类,相当于C中的全局变量,定义在方法体和语句块之外,一般定义在类的声明之下;成员变量包括实例变量和静态变量(类变量);
实例变量:独立于与方法之外的变量,无static修饰,声明在一个类中,但在方法、构造方法和语句块之外,数值型变量默认值为0,布尔型默认值为false,引用类型默认值为null;
静态变量(类变量):独立于方法之外的变量,用static修饰,默认值与实例变量相似,一个类中只有一份,属于对象共有,存储在静态存储区,经常被声明为常量,调用一般是类名.静态变量名,也可以用对象名.静态变量名调用;
局部变量:类的方法中的变量,访问修饰符不能用于局部变量,声明在方法、构造方法或语句块中,在栈上分配,无默认值,必须初始化后才能使用;
成员变量和局部变量的区别
| 成员变量 | 局部变量 | |
|---|---|---|
| 作用域 | 作用范围是整个类 | 在方法或者语句块内有效 |
| 存储位置和生命周期 | 随着对象的创建而存在,随着对象的消失而消失,存储在堆内存中 | 在方法被调用的时候存在,方法调用完会自动释放,存储在栈内存中 |
| 初始值 | 有默认初始值 | 没有默认初始值,使用前必须赋值 |
| 使用原则 | 就近原则,首先在局部位置找,有就使用;接着在成员位置找 |
重载的方法能否根据返回类型进行区分?
方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。
重载:发生在同一个类中,方法名相同参数列表不同(参数类型不同、个数不同、顺序不同),与方法返回值和访问修饰符无关,即重载的方法不能根据返回类型进行区分
重写:发生在父子类中,方法名、参数列表必须相同,返回值小于等于父类,抛出的异常小于等于父类,访问修饰符大于等于父类(里氏代换原则);如果父类方法访问修饰符为private则子类中就不是重写。
final是一个修饰符关键字,可以修饰类、方法、变量,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个常量不能被重新赋值。
finally是一个异常处理的关键字,一般作用在try-catch-finally代码块中,在处理异常的时候,通常我们将一定要执行的代码放在finally代码块中,表示不管是否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。
finalize是属于Object类的一个方法,该方法一般由垃圾回收器来调用,它的设计目的是保证对象在被垃圾收集前完成特定资源的回收。finalize 机制现在已经不推荐使用,并且在 JDK 9 被标记为 deprecated。



