Java上硅谷核心知识
- 一、Java基础部分
-
- 1.1 Java语言的主要特征
- 1.2 Java程序运行机制及运行过程
-
- 1.2.1Java两种核心机制
- 1.3Java语言环境建设
-
- 1.3.1 为什么要为JDK设置环境变量
- 1.3.2 JDK、JRE、JVM
- 二、Java基本语法
-
- 2.1 Java关键字和保留字
-
- 2.1.1 return关键字的使用:
- 2.1.2 clone
- 2.2 变量
- 2.3Java的数据类型
-
- 2.3.1 引用类型包括:
- 2.3.2 基本类型包括:
- 2.3.1 自动提升
- 2.3.2 强制准换
- 2.4运算符
- 三、数组
-
- 3.对创建数组内存结构的分析:
- 3.2一维数组的内存分析
- 3.3二维数组的内存分析
- 3.数组在算法中的应用
- 3.5需要注意的问题
- 四、oop--万物皆对象
-
- 4.与对象的关系
-
- 4.1.对象内存分析
- 4.1.2对象数组的内存分析
- 4.1.3匿名对象
- 4.2 属性(成员变量)成员之一
-
- 4.2.1成员变量(属性)和局部变量的内存分析
- 4.三类成员二:方法
-
- 4.3.重载和重写方法
- 4.3.2 方法参数的值传递机制
- 4.3.3方法的递归
- 4.四类成员之三:构造器
-
- 4.4.扩展:典型的结构:应用JavaBean
- 4.5 this关键字:指向本地的属性、方法和构造器
- 4.6super关键词调用父类指定操作
- 4. 7oop三大特性
-
- 4.7.1封装
- 4.7.2继承
-
- 4.7.2.1 何为继承
- 4.7.2.2 继承的体现:
- 4.7.2.3 Java继承的规定
- 4.7.3多态
-
- 4.7.3.1 重载
- 4.7.3.2 重写:子类可以根据需要改造从父类继承的方法
- 4.8"=="和"equals"
-
- 4.8.1 equals()使用方法
- 4.9包装类
-
- 4.9.1装箱
- 4.9.2拆箱
- 4.9.3字符串-->基本类型
- 4.9.4基本类型-->字符串
- 4.10关键字static、abstract、final
-
- 4.10.1关键字static
- 4.10.2关键字final
- 4.10.3关键字abstract
- 4.10.4 接口Interface
- 4.10.5 接口与抽象类的区别
- 4.11内部类
-
- 4.11.1 成员内部类
- 4.11.2 匿名内部类
- 五、异常处理
-
- 5.1异常类型
-
- 5.1.0 堆积溢出和堆积溢出:
- 5.1.1异常运行:
- 5.1.2.编译异常:
- 5.2异常处理机制
-
- 5.2.1 异常处理方法1:try-catch-finally
-
- 5.2.1.1 异常处理:抓抛模型
- 5.2.1.2 try-catch-finally的使用
- 5.2.1.3 说明和经验:
- 5.2.2 异常处理方法二:throws 异常类型
- 5.2.3练习
- 5.3总结:
- 六、多线程
-
- 6.多线程的优点
- 6.2进程与线程
- 6.3并行与并发
- 6.4线程的创建
-
- 6.4.1继承Thread类
-
- 6.4.1.1注意:
- 6.4.2实现Runnable接口
- 6.4.创建种创建线程的区别
-
- 6.4.3.1Runnable的好处
- 6.4.4 Thread类的相关方法
- 6.4.5线程的调度
-
- 6.4.5.1调度策略
- 6.4.5.二线程优先级
- 6.4.6线程的补充
- 6.5线程的生命周期
- 6.6 线程的同步
-
- 6.6.1线程同步解决方案----synchronized
- 6.6.2线程同步解决方案---- Lock
- 6.6.3synchronized 与 Lock 的对比
- 6.6.4 线程同步范围
- 6.6.释放锁的操作
- 6.6.不释放锁的操作
- 6.6.7线程同步应用
- 6.6.7 栗子线程同步
-
- 6.6.7.1 同步代码块
- 6.6.7.2 同步方法
- 6.6.7.3 lock锁
- 6.7 线程死锁问题 6.8 线程的通信
-
- 6.8.1 wait() 方法
- 6.8.2 notify()/notifyAll()
- 6.8.3线程通信的经典例题
- 6.9 新增线程创建方式
-
- 6.9.1 实现Callable接口
- 6.9.1 使用callable栗子
- 6.9.3 使用线程池
- 6.9.4 使用线程池栗子
- 七、Java常用类
-
- 7.1 String的特性
-
- 7.1.1 String对象创建的两种方式的内存解析
-
- 7.1.1.1String对象创建的两种方式
- 7.1.1.2 内存解析
- 7.1.2 字符串对象是如何存储的
- 7.1.3 字符串的相关练习
- 7.1.4 String常用方法
- 7.2 StringBuffer和StringBuilder
- 7.3日期时间API
-
- 7.3.1日期时间API的简单的使用
- 7.3.2 时间标准化:SimpleDateFormat的用法
- 7.3.3 Calendar类的用法
- 7.3.4 JDK8以后的时间设置
- 7.4比较器
-
- 7.4.1 Comparable接口的使用举例: 自然排序
- 7.4.2 Comparator接口的使用:定制排序
- 7.5BigInteger与BigDecimal
- 八、枚举类与注解
-
- 8.1 Enum类中的常用方法
-
- 8.1.1 在使用枚举类需要注意的地方
- 8.2 注解(Annotation)
-
- 8.2.1 四个源注解的介绍:
- 九、Java集合
-
- 9.1 Collection 接口
-
- 9.1.1 Collection 接口常用方法
- 9.1.2 Iterator迭代器接口
- 9.1.2 Collection子接口之一:List接口
-
- 9.1.2.1 ArrayList
- 9.1.2.2 LinkedList
- 9.1.2.3 Vector
- 9.1.2.4 面试题:
- 9.1.3 Collection子接口之二:Set接口
-
- 9.1.3.1 Set实现类之一:HashSet
-
- 9.1.3.1.1 向HashSet中添加元素的过程
- 9.1.3.1.2 重写 hashCode() 方法的基本原则
- 9.1.3.2 Set实现类之一:LinkedHashSet
- 9.1.3.3 Set实现类之一TreeSet
- 9.2 Map接口
-
- 9.2.1 HashMap
-
- 9.2.1.1 HashMap源码中的重要常量
- 9.2.1.2 HashMap 1.7和1.8的改变
-
- JDK1.7
- JDK1.8
- JDK1.8相较于之前的变化
- 负载因子值的大小,对HashMap有什么影响
- 9.2.2 LinkedHashMap
- 9.2.3 TreeMap
- 9.2.4 Hashtable
- 9.2.5 Properties
- 9.3 Collections工具类
- 10、IO流
-
- 10.1 File 类的使用
-
- 10.1.1 路径分隔符
- 10.1.2File类的获取功能
- 10.2 IO 流体系
- 10.3 字符流的转换
-
- 10.3.1 从硬盘的文件中写入到内存中
- 10.3.2 从内存中写出数据到硬盘的文件里
- 10.3.3 从磁盘中读取到文件到内存中,在存储到另一块磁盘文件中
- 10.4 字节流的转换
-
- 10.4.1 从硬盘的文件中写入到内存中以及复制
- 10.4.2 字节流图片视频文字的输入输出
- 10.5 缓冲流的转换
- 10.6 练习
- 11、网络编程
-
- 11.1 网络通信要素概述
- 11.2 实现网络中的主机互相通信
- 11.3 域名解析
- 11.4 TCP 和 UDP
- 12、反射
-
- 12.1Java反射机制提供的功能
- 12.2 获取Class类的实例
- 12.3 类的加载过程
- Java中的设计模式
-
- 单例(Singleton)设计模式
-
- 饿汉式
- 懒汉式
- JVM的组成
一、Java基础部分
1.1 Java语言的主要特性
- Java是一种跨平台性的语言,满足的语言(Java语言的运行依赖于JVM,不同的操作系统有不同的JVM)
- Java是一种面向对象的编程语言
- Java有一个很大的优势在于有自动回收垃圾的机制
- Java语言是健壮的。Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。
1.2 Java程序运行机制及运行过程
-
Java程序的运行过程
-
层次关系
1.2.1Java两种核心机制
-
JVM
- JVM是一个具有指令集并使用不同的存储区域。负责执行指令,管理数据,内存,寄存器。
- 对于不同的平台有不同的虚拟机,平台提供了对应的虚拟机才能运行
- 因为JVM的存在,实现了"一次编译,到处运行"
-
GC
- 自动监测对象是否超过作用域()
- 将不再使用的内存空间进行回收
- 但是Java程序任然会存在内存泄露和内存溢出问题
1.3Java语言的环境搭建
1.3.1 为什么要为JDK设置环境变量
在cmd中可以在任何地方调用JDK指令
- cmd种常用指令:
dir : 列出当前目录下的文件以及文件夹
md : 创建目录
rd : 删除目录
cd : 进入指定目录
cd.. : 退回到上一级目录
cd\: 退回到根目录
del : 删除文件
exit : 退出 dos 命令行
1.3.2 JDK、JRE、JVM
JDK是Java开发工具包 (JDK=JRE+开发工具包)
JRE是Java运行环境 (JRE=JVM+Java标准类库)
JVM是Java虚拟机
二、Java基本语法
2.1 Java的关键字和保留字
被Java语言赋予了特殊含义,用做专门用途的字符串(单词)。
- Java中有很多关键字,保留字是指以后的版本可能会用到(goto和const)
- 在Java中变量的名字不能关键字或者保留字
2.1.1 return关键字的使用:
- 结束方法
- 针对于有返回值类型的方法,使用"return 数据"方法返回所要的数据。
2.1.2 clone
克隆分为深克隆浅克隆,
Animal a2 = (Animal) a1.clone();
2.2 变量
Java是一种强类型语言
强类型语言:每一种数据都定义了明确的具体数据类型,在内存中分配了不同大小的内存空间.比如int a=10;编译前就为a分配了4个字节
弱类型语言:是指是在编译后确定数据类型,没有明显的类型,随着环境的不同,自动变换类型。比如:var a=10;编译前无法确定它的类型。
变量按作用范围可分为成员变量和局部变量
- 成员变量: 在方法体外,类体内声明的变量
- 实例变量(不以static修饰的)
- 类变量(以static修饰的)
- 局部变量: 在方法体内部声明的变量
- 形参(方法、构造器中定义的变量)
- 方法内、代码块内定义的局部变量
2.3Java的数据类型
Java的数据类型一共有两种。一种是基本类型,另一种是引用类型。
2.3.1 引用类型包括:
类(class)、接口(Interface)、数组(Array)
注意:字符串在类里面
2.3.2 基本类型包括:
byte、short、int(默认)、long、float、double(默认)、char、boolean
数据类型 | 字节数 | 位数 | 范围 | 默认值 |
---|---|---|---|---|
byte | 1 | 8 | -128~127 | 0 |
short | 2 | 16 | -2^15 ~2^15-1 | 0 |
int | 4 | 32 | -2^31 ~2^31-1 | 0 |
long | 8 | 64 | -2^63 ~2^63-1 | 0 |
boolean | 1 | 8 | true、false | false |
char | 2 | 16 | 0~65535 | 空 |
float | 4 | 32 | -2^128 ~ 2^128 | 0.0 |
double | 8 | 64 | -2^1024 ~ 2^1024 | 0.0 |
说明:float和double是怎么计算的 float、double和其它类型的计算方式是不一样的,float和double是采取科学计数法来进行计算的
float和double的范围是由指数的位数来决定的。其中float的指数位有8位,而double的指数位有11位。
float: | 1bits(符号位) | 8bits(指数位) | 23bits(尾数位) |
---|---|---|---|
double | 1bits(符号位) | 11bits(指数位) | 52bits(尾数位) |
举例:
0 01111100 01000000000000000000000==0.15625
+ 124-127 1.25 1.25*2^-3=0.15625
符号位:0代表正1代表负
指数位:是一个无符号位存在一个偏移量127,计算出的结果需要与127做差
尾数位:尾数位占23个bit,它的表达上有一个特殊点,它被认为是24个bit,第一个bit取值1,且被隐藏掉:有了这个前提,我们就比较好理解尾数的表达了:这24个bit,依次表达2^0, 2^-1, 2^-2, 2^-23,隐藏的第一位表达的指就是1。所以:尾数位全0时表达的值是1,全1时表达的最大值2 - 2^-23。
注意:
- Java中char的范围和c语言中char的范围有区别Java中char占用两个字节,范围是0–65535。
- 1byte=8bit;
- long a=12; float b=12;这两种情况不会报错,是因为自动提升的原因
- byte,short,char之间不会相互转换,他们三者在计算时首先转换为int类型。
2.3.1 自动提升
基本类型中容量小的和容量大的一起运算时,会发生自动提升现象 注意:float的范围比long的还要大。是因为它们底层的存储结构不同。float/double使用科学计数法来存储,而long使用普通的二进制来存储,也就是说一个存的是多少次方,而一个是只有多少位。
2.3.2 强制准换
是指在大容量向小容量转换时发生的,在强制转换时会有精度损失
注意:类型转换都是基本类型之间的,String不能和基本类型之间进行转换,但是包装类可以和String进行转换。如: String a = “43”; int i = Integer.parseInt(a);
2.4运算符
- 算术运算:+ - * /
- 赋值运算:
short s=2;
s=s+2;//编译不通过,类型不一致
s+=2;//编译通过,运算时不会改变类型
- 比较运算 instanceof
System.out.println("hello" instanceof String);//true
- 逻辑运算
&:逻辑与
&&:短路与
|:逻辑或
||:短路或
^:异或。相同为0不同为1
!:非
- 位运算
<<左移,相当于*2
>>右移,相当于/2
&与运算,都1为1
|或运算,有1为1
^异或运算 110^011=101==>5
~取反运算 ~6=7 (补码)0110<==>(补码)1001==>0111(源码)==>7
- 三目运算符 要求 " :"前后两种数据类型要一致 举个栗子:
//如果a<60,将a的值置为0。
int a=a>60?a:0;
- 运算符优先级
三、数组
数组是一种按照一定顺序排列,且能存储相同数据类型的集合。 需要注意的是:
- 长度一旦确定,就不能再进行修改。
- 数组的索引是从0开始的而数据库库的索引是1开始的,在连接数据库时需要注意。
3.1创建数组的内存结构的解析:
3.2一维数组的内存解析
3.3二维数组的内存解析
就是两个一维数组组成的数组栈中的引用指向堆,堆中存的也是一个引用
3.4算法中数组的应用
- 数组元素的赋值(杨辉三角、回形数等)
- 求数值型数组中元素的最大值、最小值、平均数、总和等
- 数组的复制、反转、查找(线性查找、二分法查找)
- 数组元素的排序算法(稳定性)A和B相等排序后,A和B的次序不变(应用:商品首先根据销量排序,再根据价格排序,就需要排序的稳定性)
3.5需要注意的问题
int [] arr=new int[] {
1,2,3,4,5};
System.out.println(arr);//[I@32a1bec0
char [] arr1=new char[] {
'a','b'};
System.out.println(arr1);//ab
出现这种现象是因为重载。(将char型print和int型print进行重载)
四、oop–万物皆对象
在Java中将功能结构封装在类中,通过类的实例化来调用具体功能结构
主流编程语言要么是面向过程(强调考虑怎么做),要么是面向对象(强调谁来做)。
注意:int 不是对象,因为一般情况下创建对象需要进行new。将int转换为包装类后即是对象。
举个栗子:把大象装进并冰箱
4.1类和对象的关系
面向对象的两个要素:类和对象
:是指对一类事物的概括,是抽象的、概念上的定义。 :是指存在的一个真实个体,因而也称为实例(instance)。对象可以调用类的非私有成员。创建类的对象 = 类的实例化 = 实例化类 可以理解为:类 = 抽象概念的人;对象 = 实实在在的某个人 对象一般通过new来创建。类名 对象名 = new 类名();
4.1.1对象的内存解析
4.1.2对象数组的内存解析
4.1.3匿名对象
不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。
new A().show();
注意:匿名对象主要使用在只需要进行一次方法调用
4.2 类的成员之一:属性(成员变量)
属性 = 成员变量 = field = 域、字段 使用形式: 修饰符 数据类型 属性名 = 初始化值 ;
- private int age; //声明private变量 age
变量的分类:成员变量(属性,存在于方法体外部)与局部变量(存在于方法体内部) Java中的变量都是先声明后使用,并且作用于自己的作用域
属性 | 局部变量 |
---|---|
定义在类下 | 定义在方法,构造器等内部 |
可以用权限修饰符 | 不可以用权限修饰符 |
加载到堆中 | 加载到栈中 |
有默认初始值 | 没有初始值 |
4.2.1成员变量(属性)和局部变量的内存解析
4.3类的成员之二:方法
方法 = 成员方法 = 函数 = method
方法是类或对象行为特征的抽象,用来完成某个功能操作。
方法的分类:按照是否有形参及返回值。
4.3.1方法的重载和重写
- 重载:参数个数或者参数型不同的同名方法。与返回值类型无关,只看参数列表,且参数列表必须不同。(参数个数或参数类型)。调用时,根据方法参数列表的不同来区别。
举个例子:
//返回两个整数的和
int add(int x,int y){
return x+y;}
//返回三个整数的和
int add(int x,int y,int z){
return x+y+z;}
//返回两个小数的和
double add(double x,double y){
return x+y;}
- 重写:同一个方法子类对父类方法功能的改变
public class A {
public void show() {
System.out.println("ok"); }
}
class B extends A{
@Override
public void show() {
System.out.println("no ok"); }
}
4.3.2 方法参数的值传递机制
Java只有值传递
- 当传递类型是基本类型时,传递的就是参数真实的值,在方法中对值进行修改,不影响本身的值
- 当传递类型时引用类型时,传递的就是地址的值,在方法中进行修改数据时,会影响本身的值
举个栗子:
String s="hello";
Test test=new Test();
test.change(s);
// change(String s1){
// s1="hi";
// }
System.out.println(s);
4.3.3方法的递归
一个方法体内调用它自身,注意在递归时要注意弹出时,否则会导致跳不出循环,导致栈溢出
//计算1-100之间所有自然数的和
public int sum(int num){
if(num == 1){
return 1;
}else{
return num + sum(num - 1);
} }
4.4类的成员之三:构造器
构造器的作用:创建对象;给对象进行初始化 构造器:默认构造器、非默认构造器
注意:
- 多个构造器之间构成重载关系
- 父类的构造器不可被子类继承
4.4.1拓展:构造器的典型:应用JavaBean
- 有一个无参的公共的构造器
- 有属性,且有对应的get、set方法
public class JavaBean {
private String name; // 属性一般定义为private
private int age;
public JavaBean() {
}
public int getAge() {
return age; }
public void setAge(int age) {
this.age = age; }
public String getName() {
return name; }
public void setName(String n) {
name = n; } }
4.5 this关键字:指向本地的属性、方法和构造器
this可以用来修饰、调用:属性、方法、构造器们可以理解为当前对象。 在类的方法中,我们可以使用"this.属性"或"this.方法"的方式,调用当前对象属性或方法。但是,通常情况下,我们都选择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
注意: 在类的构造器中,可以使用this()调用本类的其他构造器,在用this进行调用构造器时必须放在第一行
//boy类的marry方法
marry(Girl girl){
System.out.println("I Love girlA");
}
//girl类的marry方法
marry(Boy boy){
System.out.println("I Love boyA");
boy.marry(this);//谁调用marry,this就是谁。boyA回应 I Love girlA
}
- 我们可以用this来区分属性和局部变量。
this.name = name;
4.6super关键字调用父类中的指定操作
super和this的用法相像,this代表本类对象的引用,super代表的内存空间的标识
4. 7oop三大特性
- 封装:隐藏对象内部的复杂性,只对外公开简单的接口。便于外界调用,从而提高系统的可扩展性、可维护性。通俗的说,把该隐藏的隐藏起来,该暴露的暴露出来。
- 继承:一个子类继承一个父类,能够直接调用父类的非私有属性和方法,通过set、get也能访问私有属性。
- 多态:分为运行时多态(overload)和编译时多态(override),多态的三个必要条件 :1.要有继承(实现implements) 2.要有重写(overWrite&overRide) 3.父类引用指向子类对象
4.7.1封装
将方法和属性进行私有化,对实现细节进行隐藏,只暴露出供外界使用的接口。使用者只能通过事先定制好的方法来访问数据,可以方便地加入控制逻辑,限制对属性的不合理操作
封装的体现:Java中通过将数据声明为私有的(private),再提供公共的(public)方法:getXxx()和setXxx()实现对该属性的操作
修饰符 | 类内部 | 同一个包 | 不同包的子类 | 同一个工程 |
---|---|---|---|---|
private | √ | |||
default | √ | √ | ||
protected | √ | √ | √ | |
public | √ | √ | √ | √ |
注意:对于class的权限修饰只可以用public和default
4.7.2继承
4.7.2.1 何为继承
多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。因为有了继承就可以省略掉很多冗余的代码。
4.7.2.2 继承的体现:
- 一旦子类A继承父类B以后,子类A中就获取了父类B中声明的所有的属性和方法。特别的,父类中声明为private的属性或方法,子类继承父类以后,仍然认为获取了父类中私有的结构。只有因为封装性的影响,使得子类不能直接调用父类的结构而已。
- 子类继承父类以后,还可以声明自己特有的属性或方法:实现功能的拓展。子类和父类的关系,不同于子集和集合的关系。
4.7.2.3 Java中关于继承性的规定
- 子类继承了父类,可以直接使用父类的非私有的方法和属性。
- 在子类中,可以使用父类中定义的方法和属性,也可以创建新的数据和方法。
- 在Java 中,继承的关键字用的是“extends”,即子类不是父类的子集,而是对父类的“扩展”。
说明:所有的子类都会直接或间接继承Object类
4.7.3多态
- 多态性的使用前提: ① 类的继承关系 ② 方法的重写
- 分为运行时多态(overload)和编译时多态(override)。
4.7.3.1 重载
System.out.println()方法就是典型的重载方法,其内部的声明形式如下:
public void println(byte x)
public void println(short x)
public void println(int x)
public void println(long x)
public void println(float x)
public void println(double x)
public void println(char x)
public void println(double x)
public void println()
//这2个方法不能构成重载,会有编译错误。
public int A(int i);
public double A(int i);
//这2个方法可以形成重载
public int A(int i);
public double A(double i);
4.7.3.2 重写:子类中可以根据需要对从父类中继承来的方法进行改造
注意:子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
- 从子类到父类的类型转换可以自动进行
- 从父类到子类的类型转换必须通过造型(强制类型转换)实现
- 无继承关系的引用类型间的转换是非法的
- 在造型前可以使用instanceof操作符测试一个对象的类型
public class Test {
public void method(Person e) {
// 设Person类中没有getschool() 方法
// System.out.pritnln(e.getschool()); //非法,编译时错误
if (e instanceof Student) {
Student me = (Student) e; // 将e强制转换为Student类型
System.out.pritnln(me.getschool());
} }
public static void main(String[] args){
Test t = new Test();
Student m = new Student();
t.method(m);
} }
4.8"==“和"equals”
- == 既可以比较基本类型也可以比较引用类型。对于基本类型就是比较值,对于引用类型就是比较内存地址
- equals没有被重写过默认也是==,但是进行重写(重写的原则:比较两个对象的实体内容是否相同),重写后会比较类中的相应属性是否都相等。
4.8.1 equals()方法的使用
- 是一个方法,而非运算符
- 只能适用于引用数据类型
- Object类中equals()的定义:
public boolean equals(Object obj) {
return (this == obj);
}
说明:Object类中定义的equals()和==的作用是相同的:比较两个对象的地址值是否相同.即两个引用是否指向同一个对象实体
-
像String、Date、File、包装类等都重写了Object类中的equals()方法。重写以后,比较的不是两个引用的地址是否相同,而是比较两个对象的"实体内容"是否相同。