目录
3.1 public static void main(String[] args)
3.11 String、StringBuilder、StringBuffer 的联系和区别
3.16 byte的取值范围为什么是[-128, 127]?
3.17 finally 关键字何时执行,是否一定会被执行?
一、Java 发展历程
|- 1991年4月, 詹姆斯·高斯林 (James Gosling)博士领导的绿色计划(Green Project)开始启动,其产品就是 Java 的前身,Oak(橡树);
|- 1996年1月,JDK1.0 发布,提供了一个纯解释执行的 Java 虚拟机实现;
|- 2004年9月,JDK1.5 发布,加入了自动装箱、泛型、动态注解、枚举、可变长参数、遍历循环等;
|- 2006年12月,JDK 1.6 发布,加入锁与同步、垃圾收集、类加载等等;
|- 2011年11月, JDK1.7 发布,加入自动资源管理、switch中使用string、二进制字面量等等。
|- 2014年3月,JDK1.8 发布,加入Lambda 表达式、 函数式接口、方法与构造函数引用、访问局部变量、访问对象字段与静态变量、Annotation 注解等等
|- 2017年9月,JDK1.9 发布,加入Linking、改进的 Javadoc、集合工厂方法、 私有接口方法、多版本兼容 JAR等等。
|- 至今2020年,已经整整29年。
二、Java 和 C++
Java 是由 C++ 改进而来的语言
1.1 联系
1)面向对象编程语言;
2)实现了面向对象的思想(封装、继承、多态、抽象);
3)具有很好的重用性。
1.2 区别
C++ | Java | |
语言特点 | (1)编译型; | (1)解释型 |
(2)源代码经过编译,链接生成二进制可执行代码。 | (2)源代码经过 Java 编译器城字节码文件,经 JVM 解释称机器指令执行。 | |
继承 | 多继承 | 单继承、多接口 |
对象和过程 | (1)兼具面向对象和面向过程的特点; | (1)纯面向对象语言; |
(2)可定义全局变量和函数; | (2)无全局变量和函数; | |
(3)有指针,需要开发人员管理内存分配。 | (3)无指针,有引用,避免了使用指针可能出现的系统问题,更加安全。 | |
平台无关性 | 同一数据类型在不同的平台上分配不同的字节数 | 具有平台无关性,所有的数据类型都分配固定字节数 |
标准库 | 包含标准库,方便使用 | |
1.3 面向对象和面向过程的区别
1)出发点不同:面向对象是客观世界的思维方式;面向过程则是以事件的过程为中心。
2)层次逻辑不同:面向对象模拟客观世界,以对象的集合类来处理问题;面向过程用抽象的模块(即函数)来解决问题。
3)数据处理方式和控制程序方式不同:面向对象将数据和操作数据的方法封装在一个对象中,通过对象的方法操作数据;面向过程则是直接操作数据。
1.4 面向对象的四大特性
1)抽象:将客观事物的特征抽象出来,比如:人以及人的眼睛、鼻子,揉眼睛、摸鼻子等特征抽象出来,作为一个类的属性和方法;
2)继承:一种联结类的层次模型,新类可以从原始类中派生出来,叫做派生类,派生类继承了原始类的某些特性,原始类是派生类的父类,派生类是原始类的子类;
3)封装:将客观事物抽象成类,将事物的属性和该属性的操作封装在一个类中;
4)多态:允许不同对象对同以函数调用做出不同的响应。
1.5 面向对象的好处
1)开发效率高;
2)保证软件的鲁棒性;
3)软件的可维护性高。
三、Java 基础
3.1 public static void main(String[] args)
1)main() 函数是 Java 程序的入口方法,首先找到 main() 方法,在类加载(而非对象实例化)之后即可调用。
2)main() 函数是静态函数,存储在静态存储区,静态函数和类关联而非和对象绑定,不需要实例化对象之后再行调用,可直接通过类名调用。
3)字符串数组参数 String[] args 是开发人员在命令行状态下和程序交互的一种手段。
3.2 Java 程序初始化的顺序
1)静态变量/对象 > 非静态变量/对象;
2)父类 > 子类;
3) 变量 > 方法 > 构造函数方法;
3.3 构造函数
1)构造函数和类名相同,不能有返回值(也不能有关键字 void);
2)构造函数不可被覆盖,但可以重载;
3)构造函数在实例化的时候会被自动调用,且只执行一次;
4)如果未定义,编译器默认生成一个无参构造函数;
5)子类可以用 super 关键字显示调用父类的构造函数。
3.4 生成对象的四个方法
1)new 实例化对象;
2)Java 反射机制创建对象:通过类名就获取该类的属性和方法,以及调用该类的对象属性和方法。
3)通过 clone() 方法创建一个对象:浅复制(对对象内部基本数据类型的复制)和深复制(对对象内部对象的复制)。
4)通过反序列化方法实例化一个对象:用于网络传输数据和数据持久化;
3.5 组合和继承
1)继承:通过 extends 关键字继承父类,是 "is-a" 的关系;
2)组合:在当前类中,创建另一个类的对象,是"has-a"的关系;
3.6 重载和覆盖
覆盖 | 重载 |
垂直关系,父类和子类之间 | 水平关系,同一个类中方法之间 |
一对方法 | 多个方法 |
参数和返回值相同 | 参数列表不同,返回值可以不同,但不能只是返回值不同 |
调用方法根据对象类型决定 | 调用方法由参数决定 |
3.7 抽象类和接口
抽象方法 | 接口 | |
构造函数 mian() 方法 实现的方法 | 可以有 | 都没有 |
继承 | 子类通过 extens 关键字继承抽象方法 | 子类通过 implements 关键字实现接口 |
单继承 | 多接口实现 | |
作用域 | 变量:public、protected、private | 变量:public static final |
方法:public/protected abstruct | 方法:public abstruct | |
访问速度 | 快 | 慢 |
使用场景 | 逻辑上有层次结构的类; 既有统一的接口,又有实例变量或缺省的方法;
| 协调不同类之间的交互; 作为标志接口,将不同的类归于一类 |
相同点 | 不可被实例化 |
3.8 四个内部类
1)静态内部类;
2)成员内部类;
3)局部内部类;
4)匿名内部类。
3.9 多态
1)定义:引用变量所指向的具体对象类型,以及该引用变量调用的具体方法在运行时确定,即允许不同类型的对象对同一函数调用做出不同的响应。
2)多态存在的必要条件:继承、覆盖、重载、向下转型(父类引用指向子类对象)。
3)向上转型:
|- 不能调用子类有,而父类没有的方法;
|- 多个拥有相同父类的子类,其方法的参数一致;
4)方法调用优先级:
this.show(Object) > super.show(Object) > this.show((super)Object) > super.show((super) Object;
经典多态案例:
public class A {
public String show(D obj)
return ("A and D");
public String show(A obj)
return ("A and A");
}
public class B extends A{
public String show(B obj)
return ("B and B");
public String show(A obj)
return ("B and A");
}
public class C extends B { }
public class D extends B { }
public class Test {
public static void main(String[] args) {
A a1 = new A();
A a2 = new B();
B b = new B();
C c = new C();
D d = new D();
System.out.println("1--" + a1.show(b));
System.out.println("2--" + a1.show(c));
System.out.println("3--" + a1.show(d));
System.out.println("4--" + a2.show(b));
System.out.println("5--" + a2.show(c));
System.out.println("6--" + a2.show(d));
System.out.println("7--" + b.show(b));
System.out.println("8--" + b.show(c));
System.out.println("9--" + b.show(d));
}
}
运行结果:
1--A and A
2--A and A
3--A and D
4--B and A // a2.show(B b); 该函数在父类中并未定义,根据访问顺序,访问 this.show((super) B);
5--B and A
6--A and D
7--B and B
8--B and B
9--A and D
3.10 关键字
1、static关键字:为某一数据类型或者对象分配单一的存储空间,实现方法和属性和类关联而不是和对象关联。
1)修饰变量:内存中仅有一个全局变量;
2)修饰方法:不能访问非静态的成员变量和方法:
3)修饰代码块:在类加载阶段初始化;
4)修饰内部类:只能访问外部类的静态变量和方法。
2、final关键字:
1)修饰属性:基本类型值不可变,对象引用不可变;
2)修饰方法:不可被覆盖;
3)修饰类:不可被继承。
3、violate关键字:每次访问violate修饰的变量都会从相应的内存中仅从存取,用于修饰多线程访问的变量。
3.11 String、StringBuilder、StringBuffer 的联系和区别
1)String 不可变类,内部由final修饰的char数组组成,缺点:容易造成内存泄漏。
2)StringBuilder:可变类,非线程安全,构造函数初始化;
3)StringBuffer:可变类,线程安全,构造函数初始化。
3.12 Java 反射效率低的原因
1)Method#invoke 方法会对参数做封装和解封操作
2)需要检查方法可见性;
3)需要校验参数:实际参数与形式参数的类型匹配性;
4)JIT 无法优化:动态加载的类型。
3.13 八大基本类型?
byte, short, int, long, float, double, char, boolean
3.14 “==” 和 equals 的区别?
“==”用于比较对象地址和基本数据类型的值,equals用于比较对象的值。
3.15 package 的作用?
1、多层命名空间,解决命名冲突;
2、按功能对代码文件进行分门别类,有利于管理,一目了然清晰。
3.16 byte的取值范围为什么是[-128, 127]?
[-127, 127] 的二进制补码表示为[11111111, 01111111],-128的补码表示为10000000。
3.17 finally 关键字何时执行,是否一定会被执行?
在 “try{}”中,return 执行之前执行,不一定,发生错误或者强行退出时不执行。