JAVA 体系中分为几大类吧,每一类都值得好好研究一下。了解其原理,jdk 底层是如何实现的。一般面试的时候也会问到底层实现的原理,或者手写代码去实现。总之要想学好就要花心思了。
这里我将java 分为一下几类,和 话说面试 一样 作为一个入口,这里是Java体系入口。
Java
- Java–基础
- Java–集合类
- Java–多线程
- Java–网络通讯
- Java–IO
- Java–JDBC
- Java–JVM
文章就这么结束了,似乎太短了,那 Java–基础 就在这介绍了
Java–基础
1、标识符
标识符组成:
- 使用字母、下划线(_)、美元符($)、人民币符号(¥) 和数字(不能以数字开头)
- 大小写敏感,长度不限,不能使用关键字
命名约定:
- 类和接口名:每个字的首字母大写,含有大小写,例如:MyClass
- 方法名:首字符小写,其余的首字母大写,含大小写。尽量少用下划线,采用驼峰式命名,例如:myName
- 常量名:常量名使用全部大写字母,字与字之间用下划线分隔,例如:SIZE_NAME
- 变量名:可大小写混写,首字母小写,字间分隔符用字的首字母大写。不用下划线,少用美元符号。给变量命名是尽量做到见名知义。
2、基本数据类型和其封装类
- 基本数据类型和引用类型
- String
- float和double 精度问题
- 数组
3、访问控制级别
本类、同包、子类、不同包
private < default < protected < public
私有的private :本类
默认的default:本类、同一包
受保护protected:本类、同一包、被继承
公共的public:本类、同一包、被继承、不同包
4、逻辑运算与位运算
- 位运算
- 逻辑运算
- 方法参数传递的问题
- try{}catch(){}finally{} 中 return 的问题
5、关键字–final
- final类不能被继承,没有子类,final类中的方法默认是final的。
- final方法不能被子类的方法覆盖,但可以被继承。
- final成员变量表示常量,只能被赋值一次,赋值后值不再改变。
- final不能用于修饰构造方法。
6、关键字–static
- static:修饰的方法或变量,可以通过类名直接访问
- static:可以用来修饰类的成员变量、代码块、成员方法
- static变量: 静态变量被所有的对象所共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。
- static代码块: 在类初次被加载的时候,会按照static块的顺序来执行每个static块,并且只会执行一次。
- static方法: 静态方法中不能用this和super关键字(因为this代表对象,而静态在时,有可能没有对象),不能直接访问所属类的实例变量和实例方法,只能访问所属类的静态成员变量和成员方法。
静态变量、成员变量、局部变量的区别
- 静态变量可以被对象调用,也可以被类名调用。以static关键字申明的变量,其独立在对象之外,有许多对象共享的变量。在对象产生之前产生,存在于方法区静态区中。
- 成员变量只能被对象调用。随着对象创建而存在,随对象销毁而销毁。存在于堆栈内存中
- 局部变量在方法或语句块中申明的变量,生命周期只在定义的{}之中,不能跨方法或语句块使用。
所以,成员变量可以称为对象的特有数据,静态变量称为对象的共享数据
7、抽象类和接口
- 抽象类和接口都不能直接实例化;抽象方法必须由子类来进行重写
- 抽象类单继承,接口多实现
- 抽象类可有构造方法,普通成员变量,非抽象的普通方法,静态方法
- 抽象类的抽象方法访问权限可以为:public、protected 、default
- 接口中变量类型默认public staic final,接口中普通方法默认public abstract,没有具体实现
jdk1.8 中接口可有静态方法和default(有方法体)方法
应用场合
- 接口应用场景:
- 需要将一组类视为单一的类,而调用者只通过接口来与这组类发生联系。
- 抽象类应用场景:
- 在既需要统一的接口,又需要实例变量或缺省的方法的情况下就可以使用它
- 定义了一组接口,但又不想强迫每个实现类都必须实现所有的接口
8、方法重载和重写
Java的三大特性:封装、继承、多态。封装和继承目的都是为了代码重用,多态目的是为了接口重用。
- 封装:是把客观事物抽象成类,并且把自己的属性和方法让可信的类或对象操作,对不可性的隐藏。
- 继承:它可以使用现有类的所有功能,并在无需重新编写原来的类的情况下对这些功能进行扩展。
- 多态:允许将子类类型的指针赋值给父类类型的指针。
多态性体现:方法重载、方法重写、抽象类、接口
重写0veriding和重载Overloading
-
重写:发生在继承类中,方法名和参数列表相同,权限修饰符大于等于父类、返回值类型小于等于父类、抛出异常小于等于父类
-
重载:发生在同一个类中,方法名相同,参数列表不同,与权限修饰、返回值类型、抛出异常无关
9、类加载
1> 类加载方式
- 静态加载:编译时刻加载的类是静态加载类,new关键字来实例对象,编译时执行
- 动态加载: 运行时刻加载的类是动态加载类,反射方式加载,运行期执行
2> 创建一个对象的几种方式
- 使用new关键字
- 使用反射
- 使用clone方法
- 使用序列化
3> 类初始化时机
- 使用new 实例化对象时
- 调用静态变量时(常量除外)、静态方法
- 通过反射调用
- 初始化一个类如果父类没有初始化,先触发父类的初始化
- 执行main方法的启动类
注意:
- 子类调用父类的静态变量,子类不会被初始化。只有父类被初始化。对于静态字段,只有直接定义这个字段的类才会被初始化.
- 通过数组定义来引用类,不会触发类的初始化
- 访问类的常量,不会初始化类
初始化内容:
- 一个类的静态属性、静态块、普通属性、普通方法块、构造函数
4> 类初始化顺序
- 先加载静态的属性和静态块,此二者谁定义在前,先初始化谁
- 在加载普通属性、普通方法块,此二者谁定义在前,先初始化谁
- 然后加载构造函数,构造函数调new 谁,加载谁
- 最后调用普通方法
有继承的子类:
- 先加载静态的属性和静态块,不过先加载父类的,然后子类
- 再加载先加载父类的普通属性、普通方法块、构造函数
- 再加载先加载子类的普通属性、普通方法块、构造函数
10、深拷贝和浅拷贝
浅拷贝: 对基本数据类型进行值拷贝,对引用数据类型的引用地址进行拷贝
,此为浅拷贝。
深拷贝: 对基本数据类型进行值拷贝,对引用数据类型的内容进行拷贝
,此为深拷贝。
浅拷贝:必须实现Cloneable接口,并覆写clone()方法
public class Body implements Cloneable{
private Head head;
private int age;
public Body() {}
public Body(Head head) {this.head = head;}
@Override
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
}
深拷贝:两种方式,序列化、Clonable接口
序列化
(serialization)这个对象,再反序列化回来,就可以得到这个新的对象,无非就是序列化的规则需要我们自己来写。实现Clonable接口
,覆盖并重写clone(),除了调用父类中的clone方法得到新的对象, 还要将该类中的引用变量也clone出来。如果只是用Object中默认的clone方法,是浅拷贝的
public class Body implements Cloneable{
private Head head;
private int age;
public Body() {}
public Body(Head head) {this.head = head;}
@Override
protected Object clone() throws CloneNotSupportedException {
Body newBody = (Body) super.clone();
newBody.head = (Head) head.clone();
return newBody;
}
}
11、异常
Exception 和Error 都是继承了Throwable类
- Exception:
- 是程序本身可以预料、可以处理的异常,应该被捕获。
- Exception又分为可检查(checked)异常和不可检查(unchecked)异常。
- 可检查异常: Java编译器要求
必须捕获或抛出
- 不可检查时异常: Java编译器不要求一定捕获或抛出,
可以不做处理
。像NullPointerException、ArrayIndexOutOfBoundsException之类,
- 可检查异常: Java编译器要求
- Error:
- 是程序无法处理的错误,不便于也不需要捕获。
- 常见的比如OOM和SOF之类都是Error的子类。
12、反射
1> 反射机制概述
- 反射就是通过字节码文件找到某一个类、类中的方法以及属性等
- Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。
2> 反射的3种实现方式
- 直接通过类名.class方式获得:Class clazz = User.class;
- 通过对象的getClass()方法获取:User user =new User();Class<?> clazz =user.getClass();
- 通过全类名获取:Class<?> clazz = Class.forName(“com.bobo.User”);
3> 反射常用类
Class:类的对象
Constructor:类的构造方法
Field:类中的属性对象
Method:类中的方法对象
4> 反射机制的优缺点
-
优点:
(1)能够运行时动态获取类的实例,大大提高系统的灵活性和扩展性。
(2)与Java动态编译相结合,可以实现无比强大的功能 -
缺点:
(1)使用反射的性能较低
(2)使用反射相对来说不安全
(3)破坏了类的封装性,可以通过反射获取这个类的私有方法和属性
5 > 反射中Class.forName()和ClassLoader.loadClass()的区别
- Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块。
- ClassLoader只将.class文件加载到jvm中,不会执行static块中的内容,只有在newInstance才会去执行static块。ClassLoader.loadClass().newInstance()
- Class.forName(name,initialize,loader)通过参数控制是否加载static块。并且只有调用了newInstance()方法采用调用构造函数,创建类的对象。
13、类的关系
这一块内容 有参考博文:https://blog.csdn.net/xingjiarong/article/details/50193815
在UML类图中,常见的有以下几种关系: 泛化(Generalization), 实现(Realization),关联(Association),聚合(Aggregation),组合(Composition),依赖(Dependency)
- 泛化:是一种继承关系;
- 带三角箭头的实线,箭头指向父类
- 实现:是一种类与接口的关系;
- 带三角箭头的虚线,箭头指向接口
- 关联:是一种拥有的关系,
- 对象成员变量;
- 带普通箭头的实心线,指向被拥有者
- 聚合:是整体与部分的关系;且部分可以离开整体而单独存在;
- 在代码实现聚合关系时,成员对象通常作为构造方法、Setter方法或业务方法的参数注入到整体对象中。
- 带空心菱形的实心线,菱形指向整体
- 组合:是整体与部分的关系,但部分不能离开整体而单独存在;如公司和部门是整体和部分的关系,没有公司就不存在部门。
- 对象成员变量;
- 带实心菱形的实线,菱形指向整体
- 依赖:是一种使用的关系,即一个类的实现需要另一个类的协助;
- 局部变量、方法的参数或者对静态方法的调用
- 带普通箭头的虚线,指向被使用者
各种关系的强弱顺序:
泛化 = 实现 > 组合 > 聚合 > 关联 > 依赖
14、jdk 版本区别
JDK 8 新特性
- Lambda 表达式:允许把函数作为一个方法的参数
- 方法引用:可以直接引用已有Java类或对象(实例)的方法或构造器。与lambda联合使用,方法引用可以使语言的构造更紧凑简洁,减少冗余代码。
- 默认方法:在接口里面有了一个实现的方法
- 新编译工具:新的编译工具,如:Nashorn引擎 jjs、 类依赖分析器jdeps。
- Stream API:新添加的Stream API(java.util.stream) 把真正的函数式编程风格引入到Java中
- Date Time API :加强对日期与时间的处理
- Optional 类 :解决空指针异常。
- Nashorn, JavaScript 引擎:允许我们在JVM上运行特定的javascript应用。