Java基础知识之笔记总结分享(超详细)入门必备

 

给大家分享一篇我之前在学习java过程中的关于java基础部分的笔记,比较详细,内容也比较多。 如有问题请指出以便修改,谢谢。 篇幅较长建议收藏浏览。

里面的部分重点内容以后会做详细讲解:集合,线程,JVM,JMM内存管理,多线程。请大家多多关注。

java数据类型

Java基础知识之笔记总结分享(超详细)入门必备_第1张图片

Java数据类型

 

Java基础知识之笔记总结分享(超详细)入门必备_第2张图片

基本数据类型

1.1 char :Unicode编码的字符,或字符的整数编码,必须用单引号
float默认值是0.0f;
double默认值是0.0d;

1.2基本类型字面值规则

1.整数字面值是int类型,如果右侧赋值超出int范围,需要做转型处理

2.byte,short,char 三种比int小的整数,在自身范围内可以直接赋值。

byte d=1+3 正确,1+3编译器会自动转成4

3.浮点数字面值是double;浮点数转成整数会直接舍弃小数点后位数。

4.字面值后缀,L D F

5.字面值前缀,0b 二进制;0x 16进制;0 8进制; \u char 类型16进制。

1.3基本类型的运算规则

1.计算结果的数据类型与运算中的最大类型一致。

2.byte,short,char三种比int小的整数,计算时会自动转成int

做加法运算时,数据类型会自动转成int,除了自增加自减不进行转化外,其它情况都是无long型时,所有非int类型转成int类型;有long类型时,都转成long类型。

char类型相加,提升为int类型。

Java基础知识之笔记总结分享(超详细)入门必备_第3张图片

计算

3.整数运算溢出。Integer.MAX_VALUE+1 的负数最小值
4.浮点数运算不精确
5.浮点数特殊值 infinity 整数除0 ;Nan 负数开方

1.4 基本类型的类型转换
数字类型之间可以互相转换,从小到大自动转换,从大到小需要强制转型。
double d = 245; float d=100;自动转型。

Java基础知识之笔记总结分享(超详细)入门必备_第4张图片

基本数据类型转换

1.5运算符
&& :逻辑与(短路与),两边同为真结果才为真,短路与:左边是假,右边忽略不执行
& :不管左边结果是什么都要执行右边(&的左右两边都要参与运算)
|| :逻辑或(短路或),两边只要有一个真结果就是真,短路或:左边是真,右边忽略不执行

2.流程控制

2.1 switch:只能判断byte short char int enum jdk1.7之后的string。
从成立的case 无条件穿透所有的case包括default直到结束或者遇到break中断跳出循环;
如果所有条件都不成立,则执行default

2.2 for循环

Java基础知识之笔记总结分享(超详细)入门必备

 

2.3 break 和 continue
Break 中断、跳出循环和switch
Continue 跳过后面的代码 继续进入循环的下一轮执行
2.4 for-each循环
数组遍历、集合迭代遍历的语法简化

Java基础知识之笔记总结分享(超详细)入门必备_第5张图片

 

Java基础知识之笔记总结分享(超详细)入门必备_第6张图片

 

3.面向对象 —— 封装、继承、多态 ★ ★ ★ ★ ★

封装
1 类:模板、图纸 。类中定义对象的属性数据(成员变量),方法(成员方法)
类在第一次使用时会加载到方法区
2 对象:从模板中创建的具体实例,实例是数据的打包
新建实例时,在堆内存中,新分配内存空间给这个实例。

Java基础知识之笔记总结分享(超详细)入门必备_第7张图片

 

3 引用变量:理解成“遥控器”,保存一个实例的内存地址(引用变量保存在栈),引用变量的特殊值:null 不保存任何实例的内存地址。

Java基础知识之笔记总结分享(超详细)入门必备_第8张图片

 

4 构造方法:新建实例对象时,立即执行的一个特殊方法;构造方法必须和类同名,并且没有返回值类型。
一个类中必须有构造方法,自己没定义,系统会添加默认构造方法,构造方法一般用来给属性赋值
5 构造方法重载
一个类中可以定义多个不同参数的构造方法,是方法重载的一种体现。

Java基础知识之笔记总结分享(超详细)入门必备_第9张图片

 

 

6 方法重载Overload:同名不同参,与返回值类型无关,所有方法都可以重载。

7 this关键字:this.xxx 特殊引用,引用当前对象的地址。

this(…):构造方法之间的调用,必须是首行代码,如果有多个构造方法,会通过

this(…)调取下面的所有构造方法,完成赋值。

注意this不能在静态方法中使用

继承

Java的继承是单继承多实现,只能继承一个父类(如果不继承其他类,默认继承object类),但可以实现多个接口

1.不能继承的有:构造方法,私有成员

过程:先新建父类对象,再新建子类对象,两者作为一个整体对象,调用成员时,先找子类,再找父类

2.方法重写:override

继承的方法,在子类中重新定义父类中的方法(只能在子类中重写),方法名相同,参数的个数和类型也必须相同,返回值类型也必须相同。

方法重写返回值类型如果是基本类型应与父类的一致;重写要求方法名完全相同,返回值类型如果是基本类型或无返回值时必须一致。

3.父类的构造方法

新建子类对象时会先新建父类对象,也会先执行父类的构造方法

默认执行父类的无参构造,默认隐含调用super();

new Student() 默认执行父类无参构造

new Student(……)默认执行父类无参构造

手动调用父类的有参构造,super(参数):父类没有无参构造时必须手动调用

4.super
Super.xxxx() 方法重写时,调用父类中同一个方法的代码
Super(参数) 调用父类的构造方法,默认调用父类无参构造super(),手动调用有参构造super(),必须是首行代码
注意super不能在静态方法中使用

多态
一个对象具有多种形态的表现,多态的前提是必须有继承。
void test(父类型 o1) { };
把一个子类型的实例当做父类型来处理,所有的子类型都可以传递到该方法,被当做父类型处理;作用:一致的类型

1. 类型的转换
A. 向上转型
子类的实例转成父类型,用父类型的引用变量,来引用子类实例,向上转型后,只能调用父类定义的通用成员,子类特有成员被隐藏
B. 向下转型
已经转成父类型的子类实例,转回子类型为了对子类型进行特殊处理
2. Instanceof 运行期的类型识别
当多种子类型都被当做父类型来处理,要对某种子类型进行特殊处理,可以先判断其真实类型再向下转型——对真实类型,及其父类型判断,都返回true。eg:

if(obj instanceof CustomException){
    throw new CustomException(obj.getMessage());
}

4.数组

属于object类,用来存放一组数据的数据结构,数组是最基本的一种数据结构但不是基本数据类型,数组是相同数据类型组成的集合,数组中的元素按线性顺序排序

4.1 数组的创建
数组创建后若未指定初始值,则会依据数组类型的不同来设置默认值。。eg: 3种创业数组的方式:

新建int[]数组,长度6,默认值都是0,数组的起始地址值保存在变量a。

int[] a = new int[4];
int [] b = {1,2,3,4};
int [] c = new int [] {1,2,3,4,5};

4.2 数组的长度属性 a.length
数组一旦创立,长度不可变
最大下标 a.length-1
允许0长度的数组

4.3 二维数组
存放数组的数组

int[][] a = new int[3][2];
外围长度为3,内部3个数组长度为2,一共有4个数组,内部数组默认值0,外围数组保存的是内部数组的地址。
int[][] a = new int[3][];
只建一个外围数组长度3,3个位置都是null,之后可以建新数组放入内部。

4.4 Arrays 数组工具类

  • Arrays.toString(数组) 把数组数据连接成字符串。
  • Arrays.sort(数组) 数组排序 基本类型:优化的快速排序;引用类型:优化的合并排序。
  • Arrays.binarySearch(数组,目标值) 二分法查找,在有序数组中查找目标值下标,找不到返回 -(插入点+1)。
  • Arrays.copyof(数组,长度) 复制数组成一个指定长度的新数组。

4.5 数组 复制

  • Arrays.copyof(数组,长度) 复制数组成一个指定长度的新数组
  • System.arraycopy(原数组,原数组起始位置,目标数组,目标数组起始位置,复制的数量) ——不会创建新的数组,目标数组要事先存在。

5. 变量

1 局部变量:定义在方法中或局部代码块中,必须初始化(第一次赋值时分配内存空间)
局部变量的作用域在定义它的大括号内有效,在作用范围内不能重复定义。
2 成员变量:定义在类中,自动初始化默认值,访问成员变量受访问控制符限制;局部变量可以和成员变量同名。

6.Object类

如果一个类不继承其他类,则默认继承Object类

内部方法:

toString()获得一个对象的字符串表示。

Object中的默认实现是:“类名@地址”可在子类中重写toString方法。

equals() 当前对象与参与对象作比较是否相等。

a.equals(b) Object中的默认实现是比较内存地址。

Object中比较内存地址,基本类型默认比较内容值。

public boolean equals(Object obj) {
        return (this == obj);
}  // Object 中的equals的默认实现。

7.String 类

String是封装char[] 数组的对象。

7.1 字符串创建

Char[] a ={‘a’,’b’,’c’};
String s = new String(a);  >>>简易语法>>> String s = “abcd”

7.2 字符串的常量池
String s1 = “abcd” 字符串的字面值写法。第一次使用一个字符串字面值时,会在字符串常量池中新分配内存,再次使用相同字面值时,直接访问常量池中存在的对象,而不会重复创建。

7.3.字符串中的 equals 和 “==”
“==”比较内存地址
equals 看父类中的方法,object中的默认方法是比较内存地址,String类中重写了父类方法比较的是字符内容。如下说明:

char[] a = {'a','b','c','d'};
String s1 = new String(a);//堆中新分配内存
String s2 = "abcd"; //在常量池新分配内存
String s3 = "abcd"; //访问常量池中存在的对象
System.out.println(s1==s2); //false 比较内存地址
System.out.println(s2==s3); //true 比较内存地址
String类中重写了equals方法,方法中比较的是字符内容
System.out.println(s1.equals(s2));//true 比较字符串内容
System.out.println(s2.equals(s3));//true 比较字符串内容

7.4 字符串不可变且字符串连接效率低,每次连接都会新建字符串对象
7.5 字符串的常用方法

  • charAt(i) 获取指定位置的字符
  • length() 字符串长度,字符的数量
  • indexof()找第一个子串出现的初始位置,找不到返回-1
  • indexof(子串,start)从执行位置向后找
  • lastIndexof(子串) 从后向前找
  • subString(start)截取start到末尾
  • subString[start,end )截取[start,end )范围
  • trim()去除两端的空白字符
  • matches()用来判断是否匹配正则表达式

7.6 StringBuilder: 可变的字符序列,封装char[]数组,提供了一组方法,可以对内部封装的字符进行修改,常用来代替字符串做高效的字符串连接。

  • append() 追加字符内容,内部数组默认初始容量16,放满后翻倍+2;
  • delete(start,end) 删除区间(start,end);
  • deleteCharAt(i)删除指定位置 i;
  • insert(i,内容) 在指定位置插入内容;
  • insertCharAt(i,字符)在指定位置插入单个字符;
  • replace(start,end,内容)替换指定范围的内容;
  • StringBuilder和StringBuffer
  • StringBuilder:线程不安全,效率高;JDK1.5版本后的新类。
  • StringBuffer:线程安全,旧版本的类。

8.正则表达式

一般用来判断用户的输入内容是否符合格式要求

  • matches()字符串的方法,用来判断是否匹配
  if(s.matches(regex)) { dosomething} 
  • split(正则):用匹配的子串来拆分字符串
  String s = "aaa,bbb,ccc";
  String[] a = s.split(",");
  • replace(正则,子串)替换所有匹配的子串

9.基本类型的包装类

把基本类型当做对象来使用
byte – Byte
short – Short
int – Integer
long – Long
float – Float
double – Double
char – Character
boolean – Boolean

9.1 数字父类Number
子类:Byte,Short,Integer,Long,Float,Double,BigDecimal,BigInteger

取出基本类型值的方法
byteValue(),shortValue(),intValue(),longValue(),floatValue(),doubleValu()

9.2 Intger类

创建Integer对象: a= { value:6}

Integer a = new Integer(6);

Integer a = Integer.valueOf(6);

Integer 类中存在256个Integer缓存对象,封装-127到128;如果访问指定范围内的值,会访问缓存对象,如果超出范围,会新建对象。

9.3 Integer类的方法

字符串解析成int

Integer.parseInt();Byte.parseByte()……

Integer.toBinaryString() 转成二进制字符串

Integer.toOctalString() 转成八进制字符串

Integer.toHexString(255) 转成十六进制字符串

9.4 BigDcimal和BigInteger 类
BigDcimal精确的浮点数运算
BigInteger 超大的整数运算

BigDecimal bd = BigDecimal.valueOf(2);

方法:

  • add(BigDecimal bd)
  • subtract(BigDecimal bd)
  • multiply(BigDecimal bd)
  • divide(BigDecimal bd)
  • divide(BigDecimal bd,保留位数,舍入方式)
  • setScale(保留位数,舍入方式)

9.5 自动装箱,自动拆箱

基本类型值,自动装箱成包装对象

Integer a = 6;    编译器编译成: Integer a = Integer.valueOf(6);

自动拆箱(自动拆箱要注意null值)

int i = a;    	 编译器编译成:		int i = a.intValue();

10.抽象类 Abstract

半成品类,没有完成的类;抽象方法:没有代码,只有方法的定义,抽象类不能创建实例,主要用来被继承。

// 包含抽象方法的类一定是抽象类
public abstract class A { 
		public abstract void f(); //  抽象方法
};

抽象方法的作用:

作为通用方法,在父类中定义;要求子类,必须实现这个方法。

1)抽象类可以有自己的构造方法。

2)抽象类可以有具体的方法。

3)包含抽象方法的类一定是抽象类,必须使用abstract关键字修饰,这个方法必须由子类来实现。

4)抽象类不能使用new关键字来创建实例。

5)当一个类中只要有一个抽象方法,这个类就必须是抽象类。

6)抽象类可以定义实例变量和静态变量以及常量。

7)抽象类可以再继承抽象类,也可以继承普通的类。

11.关键字 final

内存地址不可变,可以修饰常量、类、方法

11.1 final 常量:值不可变,但引用类型因为保存的是地址,所以内容可以变。

final Point a = new Point(3,4);

a.x = 30;//对

a.y = 40;//对

11.2 final 方法不能在子类重写,但可以被继承。;final不能用于修饰构造方法,父类的private成员方法是不能被子类方法覆盖的,因此private类型的方法默认是final类型的。

11.3 final 类 不能被继承,没有子类

Static — 静态 共享的数据

静态成员属于类,而不属于实例

静态成员

用类来调用静态成员 Soldier.count

实例成员

用实例来调用实例成员 s1.id

工具方法

Math.Random() Arrays.toString() String.valueOf()

静态方法中不能直接调用实例的成员(非静态),只能用实例调用。

class A {
	public static void main(String[] args) {
  	  f();//静态调静态
	}
	static void f() {
   g();//错,静态不能直接调用非静态
    A a = new A();
    a.g();//只能用实例调用
	}
	void g(){
	}
}

静态变量保存在方法区类的空间中,只保存一份可以在所有实例中共享的数据

Java基础知识之笔记总结分享(超详细)入门必备_第10张图片

 

对象的加载过程 ★ ★ ★ ★ ★

加载类:

1.加载父类,为父类静态变量分配内存 – 后台执行不可见

2. 加载子类,为子类静态变量分配内存

3. 执行父类静态变量的赋值运算,和静态初始化块

4. 执行子类静态变量的赋值运算,和静态初始化块

新建实例:

5. 新建父类实例,为父类实例变量分配内存

6. 新建子类实例,为子类实例变量分配内存

7. 执行父类的实例变量赋值运算

8. 执行父类的构造方法

9. 执行子类的实例变量赋值运算

10. 执行子类的构造方法

12.集合

用来存放一组数据的数据结构
数组的缺点: 长度固定 ; 访问方式单一只能下标访问; 前面增删数据操作繁琐
集合的继承结构:(初学者了解常用的就可以了)

Java基础知识之笔记总结分享(超详细)入门必备_第11张图片

 

Collection 是对象集合, Collection 有两个子接口 List 和 Set,

List 可以通过下标 (1,2…) 来取得值,值可以重复,而 Set 只能通过游标来取值,并且值是不能重复的

ArrayList , Vector , LinkedList 是 List 的实现类

ArrayList: 是线程不安全的, Vector 是线程安全的,这两个类底层都是由数组实现的

LinkedList:是线程不安全的,底层是由链表实现的

Map: 是键值对集合

HashTable 和 HashMap 是 Map 的实现类

HashTable:是线程安全的,不能存储 null 值

HashMap:不是线程安全的,可以存储 null 值

ArrayList

数组列表,封装了一个数组,及其操作代码和更便捷的方法,内部数组默认初始容量10 放满后,1.5倍增长

方法:

add(数据)— 添加数据;get(int i)—访问指定下标数据; remove(int i)移除指定位置的数据,返回被移除的数据; remove(数据)— 找到第一个相等的数据,找到移除并返回true,找不到返回false; size() 元素的数量;iterator() 辅助新建迭代器

效率:

访问任意位置效率高,增删数据的效率可能降低。

LinkedList — 双向链表
方法
和ArrayList有相同的方法
LinkedList 两端数据操作方法
addFirst(数据);addLast(数据);getFirst();getLast();removeFisrt()
removeLast();

效率
两端效率高

HashMap — 哈希表、散列表 (面试必问) ★ ★ ★ ★ ★

存放键值对的数据,用键来快速定位数据,来提取键对应的值

键:不重复,无序

Hashmap中的key-value都是储存中entry数组中的

Hashmap的实现不是同步的,意味着它不是线程安全的

Hashmap的实例有两个参数影响其性能:初始容量,和加载因子

方法:

put(key,value)放入键值对数据,重复的键会覆盖旧值

get(key)获得键对应的值,键不存在,得到null

remove(key)移除键值对数据,返回被移除的值

size()键值对的数量。

哈希运算过程

HashMap内部,使用entry[]数组存放数据
 数组默认初始容量16
 放满后容量翻倍+2

key.hashCode()获得键的哈希值
 用哈希值和数组长度,运算产生下标值 i
 新建entry对象来封装键值对数据
 Entry对象,放入i 位置
	  如果是空位置,直接放入
	  如果有数据,一次equals()比较是否相等
		  找到相等的,覆盖旧值
		  没有相等的,链表连接在一起
	  负载率、加载因子超过0.75
		  新建翻倍容量的新数组
		  所有数据,重新执行哈希值,存入新数组
	  Jdk 1.8
		  链表长度到8,转成红黑树
		  树上的数据减少到6,转回成链表

hashCode()

hashCode()是object的方法,默认实现是用内存地址作为哈希值,

可以重写方法来获得相同的哈希值

哈希运算中要有相同的哈希值,才能保证计算出相同下标值,并且要equals()也要相等(equals方法也要重写),才可以覆盖旧值,否则会链表连接。

重写hashCode的惯用算法:(x.y是变量的值)

 

13.异常

封装错误信息的对象
错误信息:类型、提示消息、行号

异常的继承结构

Java基础知识之笔记总结分享(超详细)入门必备_第12张图片

 

捕获异常

try {
} catch(AException e) {
} catch(BException e) {
} catch(父类型Exception e) {
} finally {
不管出不出错,都会执行
}
如果抛出异常,并且中catch中有return语句,这个return语句会先执行,执行之后将结果保
存在缓存中,再去查看是否有finally,如果有finally就先执行finally语句,之后再返回缓存中
return的值,如果finally中也有return,那么finally中的return会覆盖掉之前缓存中的return,
即最终会返回finally中的return值

throw 手动抛出异常,执行异常的抛出动作 类似 return;当程序出现逻辑错误,不自动创建并抛出异常,可以手动判断逻辑错误,手动创建异常对象并抛出。
底层的异常往上层抛,在上层处理。

if(...) {
 AException e = new AException();
 throw e;
}

异常包装

捕获的异常对象,包装成其他类型再做抛出,多种类型简化成一种类型,不能抛出的异常包装成能抛出的异常再抛。

RuntimeException 和 其他Exception

RuntimeException— 非检查异常,编译器不检查是否有异常处理代码,存在默认的抛出管道

其他异常 — 编译器检查是否有处理代码,不处理,不能编译。

14.接口

极端的抽象类,结构设计工具,用来解耦合,隔离现实

Implements代替extends

Interface 代替class

接口的定义:

 公开的抽象方法  公开的常量  公开的内部类、内部接口

1)接口只能定义常量

2)接口只能定义抽象方法

3)接口只能继承接口,不能继承普通的类和抽象类

4)接口没有构造方法

注意:

1)在接口中定义常量时,可以不用final static修饰,因为编译器在编译时会自动加上。

2)在接口中定义抽象方法时可以省略abstract关键字,编译器在编译时同样会加上。

3)JDK1.8 中的接口可以有默认的方法实现,详情参见:interface Map。

class A implements X,Y,Z {}
class A extends B implements X,Y,Z {}  // 类可以同时实现多个接口
interface A extends X,Y,Z {}   // 接口和接口的继承

15 文件、字符操作流

File
封装一个磁盘路径字符串,提供了一组对文件、文件夹的操作方法,可以封装文件夹路径、文件路径、不存在的路径。 {path=“d:/abc”}
方法

getName() 获取文件名

getPatrent() 获取父目录

getAbsolutePath()完整路径

length() 文件字节量,对文件夹无效,会返回假数据

isFile() 判断是否是文件

isDirectory()是否是文件夹

创建、删除

createNewFile()新建文件,文件已存在不会新建,返回false;文件夹不存在会出现异常

mkdirs()逐层创建多层文件夹

delete()删除文件、空目录

目录列表

list()得到String[] 包含所有文件名 [“a.txt”, “b.mp3”, “c.jpg”]

listFiles() 得到 File[],包含所有文件的封装的File对象 [{…}, {…}, {…}]

流 Stream

数据的读写操作(io操作),抽象成数据在管道中流动

单方向流动

 输入流,只能用来读取数据(读入内存)

 输出流,只能用来输出数据(内存数据向外输出)

只能从头到尾,顺序流动一次,不能反复流动,如果要重复流动,可以重新创建新的流

InputStream,OutputStream 字节流的抽象父类

方法:

write(int b) 只输出int四个字节中,末尾的一个字节值 [1][2][3][4] —> [4]

write(byte[], start, length) 输出byte[] 数组中,从start开始的length个字节值

read() 读取一个字节值,补三个0字节,变成int [4] —> [1][2][3][4],读取结束后,再读取会返回 -1。

read(byte[] buff) 按数组的长度,读取一批字节值,存放到指定的数组中,并返回这一批的字节数量,读取结束后,再读取会返回 -1。

FileInputStream,FileOutputStream — 文件流

ObjectInputStream,ObjectOutputStream —对象序列化、反序列化

序列化 把一个对象的信息,按固定的字节格式,变成一串字节序列输出

Java基础知识之笔记总结分享(超详细)入门必备

 

方法:

writeObject(Object obj) 把对象变成一串字节序列输出

readObject() 读取序列化数据,反序列化恢复对象

Serializable 接口——被序列化的对象,必须实现 Serializable 接口

不序列化的变量

Static — 属于类,不随对象被序列化输出

Transient —临时,只在程序运行期间,在内存中存在,不会被序列化持久保存

字符编码

ASC-II 0到 127,英文、指令字符

iso-8859-1 Latin-1 西欧编码 ,把ASC-II扩展到255

CJK 编码 亚洲编码,中日韩

GBK 国标码 英文单字节,中文双字节

Unicode 万国码 常用表,双字节 生僻字 三字节或四字节

UTF-8 Unicode 的传输格式 Unicode Transformation format英文,单字节某些字符,双字节;中文,三字节;特殊符号,四字节

Java的char类型是 Unicode

Java的转码运算

Java基础知识之笔记总结分享(超详细)入门必备_第13张图片

 

InputStreamReader,OutputStreamWriter
字符编码转换流 OutputStreamWriter — 把Java的Unicode编码字符,转成其他编码输出
InputStreamReader —读取其他编码字符,转成Unicode字符

16 内部类

定义在类内部、方法内部或局部代码块内部的类,用来辅助外部实例运算,封装局部数据,或局部的运算逻辑。

非静态内部类、属于实例的内部类 非静态内部类实例,必须依赖于一个外部类的实例才能存在。
静态内部类 静态内部类,与普通的类没有区别。

局部内部类
局部定义的类型,类似于局部变量,有作用范围,只能在局部代码块内使用这种类型
局部内部类中,使用外面的局部变量,必须加 final,jdk1.8,缺省。

Java基础知识之笔记总结分享(超详细)入门必备_第14张图片

 

匿名内部类

Weapon w = new Weapon() {...};

 {} - 匿名类
 new - 新建匿名类的实例
 Weapon - 父类型
 () - super(),可传参数super(1,2,3)

17. Java内存管理

堆内存 用来存放由new创建的对象实例和数组。Java堆是所有线程共享的一块内存区域,在虚拟机启动时创建,此内存区域的唯一目的就是存放对象实例。注意创建出来的对象只包含属于各自的成员变量,并不包括成员方法。

栈内存 保存的是堆内存空间的访问地址,或者说栈中的变量指向堆内存中的变量(Java中的指针)

栈:保存局部变量的值,包括:1.用来保存基本数据类型的值;2.保存类的实例,即堆区对象的引用(指针)。也可以用来保存加载方法时的帧。常量池存在于堆中(1.7b后的新版本)。

普通类型的变量在栈中直接保存它所对应的值,而引用类型的变量保存的是一个指向堆区的指针,通过这个指针,就可以找到这个实例在堆区对应的对象。因此,普通类型变量只在栈区占用一块内存,而引用类型变量要在栈区和堆区各占一块内存。

方法区是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

18.线程

在进程内部,并行执行的任务
创建线程(两种方式)
 继承 Thread
 实现 Runnable

继承 Thread

编写 Thread 的子类,并重写 run() 方法。启动之后,自动运行 run() 方法中的代码

实现 Runnable

实现 Runnable 接口,实现它的 run() 方法,Runnable 封装在线程中执行的代码,新建线程对象时,把Runnable对象放在线程内,启动

线程的状态

Java基础知识之笔记总结分享(超详细)入门必备_第15张图片

 

线程的方法

Thread.currentThread() 获得正在执行的线程实例

Thread.sleep(毫秒值) 让正在执行的线程,暂停指定的毫秒值时长

getName(),setName() 线程名

start() 启动线程 interrupt() 打断线程的暂停状态

join() 当前线程暂停,等待被调用的线程结束

setDaemon(true) 后台线程、守护线程

JVM虚拟机退出条件,是所有前台线程结束,当所有前台线程结束,虚拟机会自动退出

不会等待后台线程结束 例如:垃圾回收器是一个后台线程。

线程同步 synchronized

让多个线程共享访问数据时,步调一致的执行。一个线程修改时,其他线程等待修改完成后才能执行;一个线程访问时,其他线程等待访问结束
任何实例,都有一个“同步锁”,synchronized 关键字,要求一个线程必须抢到同步锁才能执行

synchronized(对象) {
    共享的数据访问代码
} --抢对象的锁
synchronized void f() {
}  -- 抢当前实例的锁
static synchronized void f() {
}  --抢类的锁

你可能感兴趣的:(Java基础知识之笔记总结分享(超详细)入门必备)