JavaSE知识点总结(力推萌新学习!!!)
磨刀不误砍柴工,下面是我做为初学者,到学完Java基础的感悟。特分享给你们。
在B站官看动力节点视频,最后作出总结,为Java萌新推波助澜,更上一层楼!但愿你们在编程的道路上越走越远,愈战愈强!!!。遇到困难,善于分析;解决问题,勤于总结。耐心和坚持是咱们很是关键的,你们分享,携手解决遇到的困难,每一个人都会获得极大的进步。加油!!!
知识点的最后部分,没有过多的讲解,不是我懒了,而是不想以其昏昏,使其昭昭,把好的学习环境,学习氛围破坏了。最后的时候,但愿你们都有一份属于本身的总结。当本身学习其余的内容时,把原来的忘记,温故而知新。因此有一份本身的知识总结,不失为明智之举。在学习个人总结的时候,更多的是但愿你们参照个人学习规划来,框架摆在那儿,而内容须要本身去补充。以为一个知识点须要动手实践多少次,能够灵活运用。编程,是靠实践积累起来的。只看而不屑于作练习,敲代码的人,请止步于此。
强制交易若是你们学到,以为有帮助的话,请你们要么分享本身的知识总结,要么转发这篇文章,为后面的萌新提供一丝丝便利。另外若是文章的知识点哪里不对,或者有疑义,请你们不吝赐教,发表在评论区,或者留言给我,我及时修改以避免更多人被误导。衷心感谢!!!java
在此,也动力节点的免费分享学习资料由衷的感谢。 学习视频(万分钟,学到就是赚到!)(https://www.bilibili.com/video/BV1Rx411876f)
1.第一章:Java开发环境的搭建
【1】软件开发介绍
·软件开发
软件:一系列按照特定顺序组织的计算机数据和指令的集合,有系统软件和应用软件之分。
系统软件----操做系统
·人机交互方式
图形化界面(GUI):简单直观、使用者易接受。
命令行方式(CLI):须要有一个控制台,输入特定的指令,须要记住指令,较为麻烦。 DOS
·经常使用的DOS命令
》dir: 列出当前目录的文件以及文件夹
》md: 建立目录
》rd: 删除目录
》cd: 进入指定目录
》cd…: 退回到上一级目录
》cd: 退回到根目录
》del: 删除文件
》exit: 退出dos命令行
【2】计算机编程语言介绍
计算机语言:人与计算机交流的方式。
C C++ Java PHP Kotlin Python Scala等
机器语言 :指令以二进制代码形式存在。
汇编语言:使用助记符表示一条机器指令。
高级语言:面向过程、面向对象
【3】Java语言
SUN公司1995年推出的一门高级编程语言。
09年Oracle收购。
Java SE 标准版 桌面级应用
Java EE 企业版 企业级应用
Java ME 小型版 移动终端上
Java Card程序员
Java之父 James Gosling
【4】运行机制及运行过程
Java语言特色:
一、面向对象
二、健壮性
三、跨平台性
经过Java语言编写的代码能够在任何操做系统上运行web
核心机制--垃圾回收 垃圾回收在Java程序运行过程当中自动进行,程序员没法精确控制和干预
【5】Java的环境搭建
JDK(Java Development Kit Java开发工具包)
JRE(Java Runtime Environment Java运行环境)
JDK =JRE+开发工具集(例如javac编译工具等)
JRE=JVM+JavaSE标准类库面试
安装路径: 不能包含空格和汉字,保留版本号 环境变量:配置路径 系统变量:JDK的bin目录放到path路径下 一、(多个版本JDK)环境变量配置的哪一个JDK就用哪一个JDK 二、(想配置到用户变量 )新建一个path 三、将新建的path上移到最上面
【6】EditPlus
【7】将写好的代码以 .java 的文件类型保存
cmd Javac 编译 以后 Java 运行
【8】经常使用的开发工具算法
2.第二章:Java基础语法
【1】关键字和保留字
·关键字 【图】
·保留字:现有版本还没有使用,之后可能会使用
本身命名时,避开
goto、const
【2】标识符(Identifier)
·标识符:
Java对各类变量、方法和类等要素命名时使用的字符序列
称为标识符。
·技巧:凡是能够本身起名的地方都叫标识符。
·定义合法的标识符规则:
》由26个英文字母大小写,0-9,$或_组成
》数字不能够开头
》不可使用关键字和保留字、但能包含关键字和保留字。
》Java中严格区分大小写,长度无限制
》标识符不能包含空格。
·Java中的名称命名规范
》包名:多单词组成时全部字母都小写 xxxyyyzzz
》类名、接口名:多单词组成时,全部单词的首字母都大写:XxxYyyZzz
》变量名、方法名:多单词组成时,第一个首字母小写,后边的首字母大写: xxxYyyZzz
》常量名:全部字母都大写、多单词时每一个单词用下划线链接 :XXX_YYY_ZZZ
【3】变量
变量怎么定义
变量怎么赋值
变量的做用域
变量的分类
》基本数据类型
12488412 byte short int long float double boolean char
整型 :byte 【1】、short 【2】 、int 【4】、long【8】
浮点型:float 【4】、double【8】
字符型:char 【2】
布尔型:boolean【1】
byte :-128~127
long型变量 以L或l结尾,不加的时候认为是int型
float 定义的变量须要加f
字符编码方式(理解字符编码):DBK,UTF-8,ASCLL ISO-8859-1…
》引用数据类型
类(class)
接口(interface)
数组(array)
》基本数据类型转换
·自动类型提高(容量大小区分)
byte、char、 short -->int long float double
byte char short 运算结果是int
·强制类型转换
一、可能致使精度丢失
二、须要使用强转符
》基本数据类型与String转换
String不是基本数据类型,是引用数据类型
基本数据类型与String + :链接运算。编程
int Integer.parseInt(str) double Double.parseDouble(str) 》进制与进制间转换 二进制(binayr) 以0b或者0B开头 八进制(decimal) 以数字0开头表示 十进制 (octal) 十六进制(hex) 0-9以及A-F 以0x或者0X开头
一、标识符的命名规则有哪些?
二、标识符的命名规范有哪些?
三、Java变量按照数据类型怎么划分?并指出Java的基本数据类型有哪8种?
,并指出各自占用的空间大小。
short byte int long float double boolen char
2 1 4 8 4 8 1 2
四、说明基本数据类型变量之间自动类型提高的运算规则。
五、说明基本数据类型变量之间强制类型转换的使用规则和强转可能出现的问题。
一、float 定义变量
二、long 定义变量数组
【4】运算符
·算术运算符
·+ - * / %
·++(a=2;b=++a; a=3;b=3) ++(a=2;b=a++; a=3;b=2)
·–(a=2;b=–a; a=1;b=1) --(a=2;b=a–;a=1;b=2)
·+(“He”+“llo”) ;“Hello”)
·赋值运算符
· = += -= *= /= %=
·比较运算符(关系运算符)
·== != < > <= >= instanceof(检查是不是类的对象 “Hello” instanceof String 结果 true)
·逻辑运算符
&–逻辑与 |–逻辑或 !–逻辑非
&&–短路与 ||–短路或 ^–逻辑异或缓存
逻辑与:第一个判断合格不合格 后边的代码都要进行判断 短路与:第一个判断不合格 后边的代码不在执行 逻辑异或:判断两个是不是同样的 同样为假 不同为真 a b a&b a&&b a|b a||b !a a^b 1 1 1 1 1 1 0 0 1 0 0 0 1 1 0 1 0 1 0 0 1 1 1 1 0 0 0 0 0 0 1 0 ·位运算符(系统源码会用到,实际开发用到的少) << 左移 3<<2=12-->3*2*2=12(在必定范围内) >> 右移 3>>1=1-->3/2=1(在必定范围内) >>> 无符号右移 3>>>1=1-->3/2=1 & 与运算 6&3=2 | 或运算 6|3=7 ^ 异或运算 6^3=5 ~ 取反运算 ~6=-7 左移割去多出来的部分、右移看符号 无符号右移空缺位都用00补 面试题:最高效的方式计算 2*8 2<<3 8<<1 ·三元运算符 (条件表达式)?表达式1:表达式2 运算符优先级 想要先用的加括号
【5】流程控制
顺序结构
分支结构
循环结构安全
控制语句 if switch 循环语句 for while do while 转向语句 break continue return
【方法】(函数)
- 方法怎么定义
- 方法怎么调用
- 对方法返回值的理解
- 一个方法怎么返回值的
- 一个方法执行结束以后返回值怎么接收
- 方法的重载overload
·方法递归(递归算法)服务器
3.第三章:面向对象
·面向对象怎么理解? ·类和对象 - 什么是类 - 什么是对象 ·类怎么定义 ·对象怎么建立 ·属性怎么访问 ·方法怎么访问 ·理解JVM的内存管理 ·new出来的对象存储在哪里 ·空指针异常 ·【封装】:属性私有化,对外提供公开的setter和getter放法。 ·构造方法:conatructor ·【this关键字】 一、this是个关键字,翻译成:这个 二、this是一个引用,this是一个变量,this变量保存了内存地址指向了自身,存储在堆内存Java对象内部。 三、每一个Java对象都有自身对应的this 四、this能够出如今实例方法当中(this表明当前对象)。实例方法(不带static) 五、多数状况下this能够省略不写 六、this不能使用在带有static的方法中 七、静态方法==>静态变量 八、main方法中没有this 实例变量、实例方法的引用都须要对象。 修饰符列表上有static 采用“类名.“的方式访问,显然这个方法在执行的时候不须要对象的参加。 static的方法调用不须要对象,直接使用类名,因此执行过程当中没有当前对象,因此不能使用this ·【static关键字】 一、static关键字能够修饰成员变量和成员方法 - 特色: 被static修饰的成员变量会变成静态变量,静态变量不仅仅仅仅只是属于某一个对象的, 而是属于类的,因此静态变量会被该类的全部对象共享,也就是说全部该类的对象使用的是同一份数据。 二、实例方法和静态方法的访问 静态方法只能访问静态成员, 实例方法能够访问静态和实例成员。 之因此不容许静态方法访问实例成员变量, 是由于实例成员变量是属于某个对象的, 而静态方法在执行时,并不必定存在对象。 一样,由于实例方法能够访问实例成员变量, 若是容许静态方法调用实例方法,将间接地容许它使用实例成员变量, 因此它也不能调用实例方法。基于一样的道理,静态方法中也不能使用关键字this。 三、static代码块(类构造的时候执行,多个代码块时,按照顺序依次执行) static关键字还有一个比较关键的做用就是 用来造成静态代码块以优化程序性能。 static块能够置于类中的任何地方, 类中能够有多个static块。 在类初次被加载的时候, 会按照static块的顺序来执行每一个static块, 而且只会执行一次。 (JDBC class.format()处有用到静态代码块) 四、Java中规定:static不容许修饰局部变量。 ·【super关键字】 一、用法: - super能够用来引用直接父类的实例变量。 - super能够用来调用直接父类方法。 - super()能够用于调用直接父类构造函数 二、注意: 若是咱们没有显式调用super来初始化父类的话, 那么Java会隐式的调用super(); 来调用父类无参构造函数并把它放在构造函数的第一行 ·【final】 一、final 修饰类,表示这个类不能被继承 final 类中的全部成员方法都会被隐式的指定为final方法 (在使用final修饰类的时候,要注意谨慎选择,除非这个类真的在之后不会用来继承或者出于安全的考虑,尽可能不要将类设计为final类。) 二、final修饰方法 “使用final方法的缘由有两个。第一个缘由是把方法锁定,以防任何继承类修改它的含义;第二个缘由是效率。在早期的Java实现版本中,会将final方法转为内嵌调用。可是若是方法过于庞大,可能看不到内嵌调用带来的任何性能提高。 在最近的Java版本中,不须要使用final方法进行这些优化了。“
所以,若是只有在想明确禁止 该方法在子类中被覆盖的状况下才将方法设置为final的。
( 注:类的private方法会隐式地被指定为final方法。)
三、修饰变量
修饰变量是final用的最多的地方
对于一个final变量,若是是基本数据类型的变量,则其数值一旦在初始化以后便不能更改;若是是引用类型的变量,则在对其初始化以后便不能再让其指向另外一个对象。
public static void main(String[] args) {
final int i= 1;
// i =20;
//java: 没法为最终变量i分配值
final Object obj =new Object();
obj =new Object();
//java: 没法为最终变量obj分配值
}
·【继承】 ·方法的覆盖 一、何时进行方法重写? 若是父类中的方法已经没法知足当前子类的业务需求,须要将父类中的方法进行从新写一遍。就是要改变父类的行为。 注意若是重写父类中的方法以后,子类对象调用的必定是重写以后的方法。 二、发生方法覆盖的条件 - 发生在具备继承关系的两个类之间 - 必须具备相同的方法名,相同的返回值类型,相同的参数列表 - 重写的方法不能比被重写的方法拥有更低的访问权限 - 重写的方法不能比被重写的方法抛出更宽泛的异常 - 私有的方法不能被覆盖 - 构造方法没法被覆盖,由于构造方法没法被继承 - 静态方法不存在覆盖 - 覆盖指的是成员方法,和成员变量无关。 继承最基本的做用是:代码重用。继承最重要的做用:方法能够重写。 【方法重载】 - 方法名称相同 - 方法参数类型、个数、顺序至少有一个不一样 - 方法的返回值类型能够不一样 - 方法的修饰符能够不一样 - 方法重载只能出现同一个类中 ·【多态】:多态的基础语法+多态的做用(OCP开闭原则) 一、多态使用的好处: - 消除了类之间的耦合关系 - 大大提升了程序的简洁性和可拓展性 二、子类对象的多态性,并不适用于属性 三、OCP开闭原则是指一个软件实体如类、模板和函数应该对扩展开放,对修改关闭。 强调的是用抽象构建框架,用实现扩展细节。 开闭原则是面向对象设计中最基础的设计原则。它指导咱们应该如何创建稳定灵活的系统。 例如:咱们版本更新,尽量不修改源代码,可是能够增长新功能。 ·【抽象类】 一、抽象类是指在普通类的结构里面增长抽象方法的组成部分 二、抽象方法:普通方法上面会有{},这个表示方法体,有方法体的方法必定能够被对象直接调用,而抽象方法是指没有方法体的方法, 同时抽象方法还必须使用关键字abstract作修饰。 而拥有抽象方法的类就是抽象类,抽象类要使用abstract关键字声明。 三、抽象方法的使用原则以下: - 抽象方法必须为public 或者protected(由于若是为private,则不能被子类继承,子类边没法实现该方法),缺省状况下默认为public - 抽象类不能直接实例化,须要依靠子类采用向上转型的方式处理 - 抽象类必须有子类,使用extends继承,一个子类只能继承一个抽象类 - 子类(若是不是抽象类)则必须覆盖抽象类中的全部抽象方法。(若是子类没有实现父类的抽象方法,则必须将子类也定义为abstract类) 四、抽象类的使用限制 (1)抽象类中有构造方法么? 因为抽象类里会存在一些属性,那么抽象类中必定存在构造方法,其存在目的是为了属性的初始化。 而且子类对象实例化的时候,依然知足先执行父类构造,再执行子类构造的顺序。 (2)抽象类能够用final声明么? 不能,由于抽象类必须有子类,而final定义的类不能有子类; (3)抽象类可否使用static声明? 外部抽象类不容许使用static声明,而内部的抽象类运行使用static声明。使用static声明的内部抽象类至关于一个外部抽象类,继承的时候使用“外部类.内部类”的形式表示类名称。 ·【接口】 - 接口的定义:接口是一系列方法的声明,是一些方法特征的集合,一个接口只有方法的特征没有方法的实现,所以这些方法能够在不一样的地方被不一样的类实现,而这些实现能够具备不一样的行为(功能)。 - 接口的特色: 一、Java接口中的成员变量默认都是public 、static、final类型的(均可以省略),必须被显示初始化,即接口中的成员变量为常量。 二、Java接口的方法默认都是public、abstract类型的(均可省略),没有方法体,不能被实例化 三、Java接口中的方法只能包含public static final 类型的成员变量和public abstract 类型的成员方法 四、接口中没有构造方法,不能被实例化 五、一个接口不能实现(implement)另外一个接口,可是它能够继承多个其余接口 六、Java接口必须经过类来实现它的抽象方法 七、当类实现某个Java接口时,它必须实现接口中的全部抽象方法,不然这个类必须声明为抽象类 八、不容许建立接口的实例,但容许定义接口类型的引用变量,该引用变量引用实现了这个接口的类的实例 九、一个类只能继承一个直接的父类,但能够实现多个接口,间接的实现了多继承。 - 接口的用法 两个及以上的类拥有相同的方法,可是实现功能不同,就能够定义一个接口,将这个方法提炼出来,在须要使用该方法的类中去实现,就免去了定义系统方法的麻烦。 ·例如:人会吃饭,睡觉 人有三个身份 学生、 教师 、校领导 吃的不同,住的不同 可是都会吃、住。 此时定义一个接口 interface Peron{ void eat(); void sleep(); } ·【Object类中的经常使用方法】 equals hashCode toString finalize clone.. ·【内部类】:重点掌握匿名内部类。 内部类: 1.什么是内部类? 内部类:在类的内部又定义了一个新的类。被称为内部类。 2.内部类的分类 静态内部类:相似于静态变量 实例内部类:相似于实例变量 局部内部类:相似于局部变量 3.匿名内部类 new 接口{实现方法} ·【向上转型 ||向下转型】 - 向上转型 经过子类对象(小范围)实例化父类对象(大范围),这种属于自动转换 向上转型时,父类只能调用父类方法或者子类覆写后的方法,而子类中的单独方法则是没法调用的. public class A{ public void fun(){ sout("A"); } } public class B extends B{ public void fun(){ sout("B"); } } main(){ A a= new B(); //向上转型 自动的 a.fun(); } 输出: B - 向下转型 经过父类对象(大范围)实例化子类对象(小范围),这种属于强制转换
public class C extends A{
public void fun() {
System.out.println(“C”);
}
public void funC(){ System.out.println("C的方法啊"); }
}
public class ABCtest {
public static void func(A a){ a.fun(); if( a instanceof B){ B b =new B(); b.funB(); } else if(a instanceof C){ C c= new C(); c.funC(); } } public static void main(String[] args) { func(new A()); func(new B()); func(new C()); }
}
结果:A
B
B的方法
C
C的方法啊
【JVM内存结构——堆、栈、方法区】
方法区;类加载器classloader,将硬盘上的xxx.class字节码文件装载到JVM的时候,会将字节码文件存放到方法区当中,也就是说方法区中存储的是代码片断。 (由于类须要加载,因此方法区当中最早有数据。) 栈内存:在方法被调用的时候,该方法须要的内存空间在栈中分配。 方法只有在调用的时候才会在栈中分配空间,而且调用的时候就是压栈。 方法执行结束以后,该方法所须要的空间就会释放,此时发生弹栈动做。 (给main方法分配空间)
1、定义
一、堆:FIFO队列优先,先进先出。jvm只有一个堆区被全部线程所共享!堆存放在二级缓存中,调用对象的速度相对慢一些,生命周期由虚拟机的垃圾回收机制定。
二、栈:FILO先进后出,暂存数据的地方。每一个线程都包含一个栈区!栈存放在一级缓存中,存取速度较快,“栈是限定仅在表头进行插入和删除操做的线性表”。
三、方法区:用来存放方法和static变量。
2、存储的数据类型
一、堆用来存储new出来的对象和数组
二、栈用来存储基本类型变量和对象的引用变量的地址
三、方法区存储方法和static变量
3、优缺点
一、堆的优势-能够动态的分配内存大小,生命周期不肯定。缺点-速度略慢
二、栈的优势-速度快,缺点-存在栈中的数据大小和生命周期必须是明确的,缺乏灵活性。
4.第四章:数组
数组的内存解析
栈 堆 方法区
局部变量 new出来的结构 常量池
(对象、数组) 静态域
一、写出一维数组初始化的两种方式。
int[] arr=new int[5];//动态初始化
int[] arr=new int[]{};//静态初始化
二、写出二维数组初始化的两种方式。
int[][] arr=new int[len][len];//动态初始化1
int[][] arr=new int[len][];//动态初始化2
int[][] arr=new int[][]{
{},{}};//静态初始化
三、如何遍历以下的二维数组
int[][] arr=new int[][]{
{1,2,3},{6,7,8}};
for(int i=0;i<arr.length;i++){ for(int j=0;j<arr[i].length;j++){ System.out.print(arr[i][j]); } System.out.print("\n"); }
四、不一样类型的一维数组元素的默认初始化值各是多少?
整型:0
浮点型:0.0
char :0
boolean:false
引用类型:null
五、一维数组的内存解析。
*数组一旦初始化,其长度就是肯定的,不能更改。
【Arrays工具类的使用】
查看帮助文档。
经常使用方法 /* * boolean equals(int[] a,int[] b) 判断两个数组是否相等 * String toString(int[] a) 输出数组的信息 * void fill(int[]a ,int val) 将指定值填充到数组之中 * void sort(int[] a) 对数组进行排序 * int binarySearch(int[] a,int key) 对排序后的数组进行二分检索指定的值 * * 常见异常 /* *数组角标越界异常:ArrayIndexOutOfBoundsException *空指针异常:NullPointerException **/ 【String[] args】 当你使用命令行bai的形du式运行.class文件时,向你的类传递参数zhi. C:\>java YourClassName 参数1 [参数2 参数3 ....]参数之间用一个空格bai做为间隔符. String[] args 这个字符串数组是保存运行main函数时输入的参数的 ,例如main函数所在的类名为test 那么你在cmd运行 java test a b c 时, args[0] = a ,args[1]=b, args[2]=c 你就能够在你的程序中调用你输入的这些变量了。 【数组的扩容】 ① int[] arr2=new int[arr1.length*2] //新数组长度 for(int i=0;i<arr1.length;i++){ //复制 arr2[i]=arr1[i]; } ② int[] arr2=java.util.Arrays.copyOf(原数组名,新数组长度); ③ int[] arr2=new int[arr1.length*2] System.arraycopy(原数组名,起始下标,新数组名,起始下标,复制长度); (本质就是用一个新的容量大的数组拷贝原数组的值)
一、使用冒泡排序,实现以下的数组从小到大排序
int[] arr=new int[]{34,5,22,-98,6,-76,0,-3};
二、如何反转上面的数组,请代码实现
三、复制上述数组,获得一个新的数组
四、使用线性查找,从上述数组中查找22是否存在,存在返回所在位置
的索引,不存在,输出提示信息
五、数组中常见的异常有哪些?请举例说明。
5.第五章 异常
·异常怎么理解
程序执行过程当中出现了不正常状况,这种不正常状况叫作,异常。
java语言是很完善的语言,提供了异常的处理方式,一下程序执行过程当中出现了不正常的状况,
Java把该异常信息打印输出在控制台,供程序员参考,程序员看到异常信息在以后,能够对
程序进行参数修改,让程序更加的健壮。
- 异常信息是JVM打印的。
·异常在Java中有什么用?
- 给程序员提示程序错误信息,一边修改。
- 加强健壮性
·异常在Java中以什么形式存在?
- 异常以类和对象的形式存在
public static void main(String[] args) {
NullPointerException n =new NullPointerException(“空指针异常”);
System.out.println(n);
//java.lang.NullPointerException: 空指针异常
}
·异常的继承结构图
Throwable(父类)
ERROR(虚拟机错误、内存溢出、线程死锁) Exception(RuntimeException、IO异常、SQL异常)
RuntimeException(空指针异常NullPointerException、
数组下标越界异常 ArrayIndexOutOfBoundsException、
算数异常ArithmeticException、
类型转换异常ClassCastException)
·什么是编译时异常
是RuntimeException之外的异常,
类型上都属于Exception类及其子类。
从程序语法角度讲是必须进行处理的异常,
若是不处理,程序就不能编译经过。
如IOException、SQLException等以及用户自定义的Exception异常,
通常状况下不自定义检查异常。
·什么是运行时异常
都是RuntimeException类及其子类异常,
如NullPointerException(空指针异常)、
IndexOutOfBoundsException(下标越界异常)等,
这些异常是不检查异常,程序中能够选择捕获处理,
也能够不处理。这些异常通常是由程序逻辑错误引发的,
程序应该从逻辑角度尽量避免这类异常的发生。
运行时异常的特色是Java编译器不会检查它,也就是说,
当程序中可能出现这类异常,即便没有用try-catch语句捕获它,
也没有用throws子句声明抛出它,也会编译经过。
·ERROR (错误)是程序没法处理的错误。表示代码运行时JVM出现问题。如JVM运行错误、类定义错误。
·异常的两种处理方式:
第一种:捕捉try catch
输出打印异常信息,
第二种:throws(声明该方法出现此类异常时上抛)
调用方法时必须对这种异常进行预先的处理,若是不处理就会报错。
*未报告的异常错误java.lang.ClassNotFoundException; 必须对其进行捕获或声明以便抛出
·finally子句的用法
- 在finally子句中的代码是最后执行的,而且是必定执行的,即便是try语句中的代码出现异常
必须和try一块儿出现。不能单独编写
- finally语句一般在哪些状况下执行?
流使用完要关闭,占用资源的关闭时,在finally子句中关闭。
·怎么自定义异常
两步:
第一步:编写一个类继承Exception(编译时异常)或者RuntimeException(运行时异常)
第二步:提供两个构造方法,一个无参数的,一个带有String 参数的
·怎么手动抛异? throw new RuntimeException
·异常对象的两个方法?
e.getMessage();获取异常的简短信息
e.printStackTrace();打印异常追踪堆栈信息
·方法重写与异常
·关键字:
try
catch
finally
throw
throws
- try catch
一、catch后面的小括号中的类型能够是具体的异常类型,也能够是该异常类型的父类型
二、catch能够写多个,建议catch的时候,精确的一个一个处理,这样有利于程序的调试
三、catch写多个的时候,从上到下,必须遵循从小到大的原则
【上报和捕捉】
但愿调用者知道就上报,但愿程序继续运行就捕捉。
【JDK8的新特性】 :catch(异常1|异常2)
【final、finally、finalize】
final是一个关键字 表示最终的、不变的
finally也是一个关键字
finalize 是一个标识符。是一个方法。
6.第六章 经常使用类
·String类的实现原理,内存存储方式。
- String str = “abc”;
至关于; char data[] = {‘a’, ‘b’, ‘c’};
String str = new String(data);
- 存储在方法区的常量池中
双引号建立的字符串能够直接用,new出来的字符串当对象处理
·String一旦建立就不会改变,若是有+ 那么实际新建三个字符串
-字符串的比较:s1.equals(s2);
·String类的构造方法
- String s = new String(“abc”);
- String s =“abc”;
·String类的经常使用方法
- 见JDKAPI帮助文档
·StringBuilder StringBuffer的经常使用方法?以及和String的区别
- java字符串是不可变的,开发过程当中,须要大量的字符串拼接,会占用大量的方法区内存,形成内存空间的浪费。
StringBuffer 进行字符串拼接。
- 区别
StringBuilder:初始容量16(线程不安全)
StringBuffer:初始容量16 (线程安全的synchronized修饰表示StringBuffer 在多线程环境运行是安全的)
·八种基本数据类型对应的包装类
基本数据类型 包装类型
--------------------------
byte java.long.Byte
short java.lang.Short
int java.lang.Integer
long java.lang.Long
float java.lang.Float
double java.lang.Double
boolean java.lang.Boolean
char java.lang.Character
Integer为表明
自动装箱和自动拆箱是什么?
-JDK 1.5以后支持自动拆箱和自动装箱
·自动装箱:基本数据类型自动装换成包装类
·自动拆箱:包装类自动转换成基本数据类型
·有了自动拆箱以后,Number类中的方法就用不着了;
Integer、int、String三种类型互相转换 ·数字的处理 NumberFormat BigDecimal(财务数据) ·日期处理 怎么获取系统当前时间 Date date =new Date(); 怎么获取毫秒 date.getTime(); 怎么进行日期格式化 怎么将字符串日期转换成日期类型Date SimpleDateFormat sdf =new SimpleDateFormat("yyyy-mm-dd hh:MM:ss SSS"); Date date= sdf.parse("String"); ·枚举类型 返回值两种 Boolean 返回值多种 使用enum枚举类型
public class enumTest {
public static void main(String[] args) {
Serson s =fun();
System.out.println(s);
}
public static Serson fun(){
return Serson.SPRING;
}
}
enum Serson{
SPRING,SUMMER,AUTOMU,WINTER
}
·随机数 import java.util.Random; Random random =new Random(); int i =random.nextInt(10); 生成0-1之间的随机数。 double random = Math.random();
7.第七章 集合
·集合概述
1.1什么是集合?有什么用?
数组其实就是个集合,集合实际上就是一个容器,能够容纳其余类型的数据。
集合为何说在开发中使用较多?
集合是一个容器,一个载体,能够一次容纳多个对象。
·集合中均可以存储什么元素 集合不能直接存储基本数据类型,另外集合也不能直接存储Java对象, 集合当中存储的都是Java对象的内存地址,或者说集合中存储的是引用 注意: 集合在Java中自己是一个容器 集合在任什么时候候存储的都是"引用" ·在Java中集合分为两大类: 一类是单个方式存储元素: 单个方式存储元素,这一类集合中超级父接口:java.util.Collection; 一类是以键值对的方式存储元素 以键值对的方式存储元素,这一类集合中超级父接口:java.util.Map; ·集合的继承结构图Collection ·集合的继承结构图Map ·Collection接口中经常使用的方法 见帮助文档 ·Collection集合的遍历方法 ~Iterator it =Collection.Iterator(); it是迭代器对象 遍历集合 while(it.hasNext()){ Object o = it.next(); System.out.println(o); } ·List集合特色 List集合中特有的方法 ~get() ~indexOf() ~set() ~remove() ~lastIndexOf() ·Set集合特色 ·ArrayAList集合 底层是什么数据结构 ArrayList集合的初始化容量 ArrayList集合的扩容是怎样的? (01) ArrayList 其实是经过一个数组去保存数据的。当咱们构造ArrayList时;若使用默认构造函数,则ArrayList的默认容量大小是10。 (02) 当ArrayList容量不足以容纳所有元素时,ArrayList会从新设置容量:新的容量=“(原始容量x3)/2 + 1”。 (03) ArrayList的克隆函数,便是将所有元素克隆到一个数组中。 (04) ArrayList实现java.io.Serializable的方式。当写入到输出流时,先写入“容量”,再依次写入“每个元素”;当读出输入流时,先读取“容量”,再依次读取“每个元素”。 ·LinkedList集合 底层是什么数据结构 双向链表 链表数据结构的优势和缺点 优势:在指定位置增长删除元素效率高 缺点:查找效率低 ·Vectot集合 底层是什么数据结构 数组 Vector集合的初始化容量 Vector集合的扩容是怎样的 Vector和ArrayList集合的区别 synchronized!!! ·HashSet集合底层是HashMap ·SortedSet接口,可排序的集合,子类有:TreeSet ·TreeSet集合底层是TreeMap集合 ·Map集合中经常使用的方法 ·HashMap集合的底层数据结构 哈希表 哈希算法是怎样的 为何要重写hashcode equals HashMap的默认加载因子 HashMap集合的初始化容量 Hash Map的扩容是怎样的 借鉴文章: https://blog.csdn.net/zhengwangzw/article/details/104889549?utm_medium=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight&depth_1-utm_source=distribute.pc_relevant_t0.none-task-blog-BlogCommendFromMachineLearnPai2-1.edu_weight ·Hash table集合底层是什么数据结构 ·Hashtable下的子类Properties有必定的理解 ·Sorted Map的key可排序是如何实现的 ·TreeMap集合底层是一个二叉树的数据结构,他是怎么样的一个数据结构 ·Map集合的遍历有多种方式须要掌握
public class Test4 {
public static void main(String[] args) {
HashMap<Phone,String> map = new HashMap<>();
map.put(new Phone(“Apple”,7000),“美国”);
map.put(new Phone(“Sony”,5000),“日本”);
map.put(new Phone(“Huawei”,6000),“中国”);
Set<Map.Entry<Phone, String>> entries = map.entrySet();
for (Map.Entry<Phone, String> entry : entries) {
System.out.println(entry.getKey().getBrand()+"="+entry.getKey().getPrice()+"="+entry.getValue());
}
}
}
·集合的泛型
泛型标志:<>
·集合的工具类:Collection的经常使用方法
总结:(全部实现类) ArrayList:底层是数组 LinkedList:底层是双向链表 Vector:底层是数组,线程安全的,效率较低,使用较少 HashSet:底层是HashMap,放到HashSet集合中的元素等同于放到HashMap集合的key部分了 TreeSet:底层是TreeMap,放到TreeSet集合中的元素等同于放到Tree Map集合key部分了 HashMap:底层是哈希表,之不够线程安全的,效率较低,使用较少 Properties:是线程安全的,而且key和value只能存储字符串 TreeMap:底层是二叉树,TreeMap集合的key能够自动按照大小顺序排序 List集合存储元素的特色: 有序可重复 有序:存进去的顺序和取出的顺序相同,每个元素都有下标 可重复:有一个1 还能够在存1 Set集合存储元素的特色: 无序不可重复 无序:存进去的顺序和取出的顺序不必定相同,另外Set集合元素没有下标 不可重复:有1 了不能在存储1了 Sorted(SortedMap)集合存储元素的特色: 首先是无序不可重复,可是SortedSet集合中的元素是可排序的。 无序:存进去的顺序和取出的顺序不必定相同,另外Set集合中元素没有下标 可排序:能够按照大小顺序排序 Map集合的key,就是一个Set集合 在Set集合中放数据,其实是放到了Map集合的key部分。
8.第八章 IO流(I:Input O:Output)
skip() 跳过并从输入流中丢弃 n字节的数据。 available()返回今后输入流中能够读取(或跳过)的剩余字节数的估计值,而不会被下一次调用此输入流的方法阻塞。 ~重点掌握哪些流?16个流 文件专属: FileInputStream FileOutputStream FileReader FileWriter 缓冲流专属: BufferedReader BufferedWriter BufferdInputStream BufferdOutputStream 转换流:(将字节流转换成字符流) InputStreamReader OutputStreamWriter 对象专属流: ObjectInputStream ObjectOutputStream 数据流专属: DataInputStream DaraOutputStream 标准输出流: PrintWriter PrintStream ~流的分类?(在Java中只要"类名"以Stream结尾的都是字节流,以"Reader/Writer"结尾的都是字符流) 输入流 输出流 字节流 字符流(四你们族的首领都是抽象类) 节点流 包装流 (当一个流的构造是一个流的时候,构造里的这个流叫作节点流,外部的流叫作包装流)。 一种方式是按照流的方向进行分类: 之内存做为参照物, 往内存中去,叫作输入(Input),或者叫作读(Read) 从内存中出来,叫作输出(Output),或者叫作写(Write) 另外一种方式是按照读取数据方式不一样进行分类: 有的流是按照字节的方式读取数据,一次读取1个字节byte,等同于一次读取8个二进制位,这种流是方能的, 什么类型的文件均可以读取,例如:文本文件,图片,声音文件,视频 有的流是按照字符的方式读取数据的,一次读取一个字符,这种流为了方便读取文本文件而存在的,这种流不能读取:图片、声音、视频等文件,只能读取纯文本文件, 连word都不没法读取。 全部的流都实现了: java.io.Closeable接口,都是可关闭的。 流毕竟是一个管道,是内存和硬盘之间的通道, 会耗用资源,用完必定要关闭。 全部的输出流都实现了: java.io.Flushable接口,都是可刷新的,都有flush()方法。 养成了一个好习惯,输出流在最终输出以后,必定要记得flush()刷新一下 。这个刷新表示将管道当中剩余未输出的数据强行输出完,刷新的做用:清空管道 注意:若是没有flush()可能会缺失数据 ~可以使用流完成文件的复制 ~掌握File类的经常使用方法。 1.File类和四你们族没有关系,因此不能完成文件的读和写。 2.File对象表明什么? 文件和目录路径名的抽象表示形式。 C:\Drivers 这是一个File对象 C:\Drivers\readMe.txt 这也是File对象 一个File对象有可能对应的是目录,也多是文件。 File只是一个路径名的抽象表示形式。 3.经常使用方法: ~见文件夹 File类经常使用方法 FileInputStream:
/*
1.文件字节输入流,万能的,任何类型的文件均可以采用这个流来读。
2.字节的方式,完成输入的操做,完成读的操做(硬盘—>内存)
*/
BufferedReader:
1.带有缓冲区的字符输入流
2.使用这个流的时候不须要自定义char数据,自带缓冲。
DataInputStream
1.写的文件记事本打不开,以什么顺序写入的,就以什么顺序读取。
PrintStream
1.标准的字节输出流,默认输出到控制台的
2.标准的输出流不须要close()关闭
/*
标准的输出流(日志框架原理)
*/
public class PrintStreamTest {
public static void main(String[] args)throws Exception {
PrintStream ps= new PrintStream(new FileOutputStream(“D:\从零开始\java\IO流\PrintStreamFile.txt”));
//改变输出方向
System.setOut(ps);
ps.println("hello"); ps.println("你好"); ps.println("My Girl");
}
}
ObjectOutStream
类要实现Serializable接口(JVM自动生成序列化版本号)
建议:手动写序列化版本号
private static final long serivalVersionUID=???
序列化和反序列化
序列化多个对象:将对像放到List集合中,将集合序列化、反序列化
transient关键字:修饰属性时不参与序列化
Java语言中采用什么机制区分类的?
第一:首先经过名字进行比对,若是类名不同,确定不彷佛同一类
第二:若是类名同样,再怎么进行类的区别,靠序列化版本号进行区分。
自动生成的序列化版本号有什么缺陷?
后期不能修改代码
最终结论: 凡是类实现了Serializable,给类一个固定不变的版本号。
IO和Properties联合使用
/*
IO 和Properties 联合使用
*/
import java.io.FileReader;
import java.util.Properties;
public class IOTest {
public static void main(String[] args) throws Exception{
FileReader fr =new FileReader(“D:\从零开始\java\IO流\IOProperties.txt”);
Properties p =new Properties();
p.load(fr);
String username = p.getProperty(“username”);
System.out.println(username);
fr.close();
}
}
9.第九章 多线程
1.什么是进程?什么是线程?
进程是一个应用程序,(一个进程是一个软件)
线程是一个进程的执行场景/执行单元
一个进程能够启动多个线程
2.对于Java程序来讲,当在DOS命令窗口输入:
Java helloWorld回车以后,
会先启动JVM,而JVM就是一个进程
JVM在启动一个主线程调用main方法。
同时再启动一个垃圾回收线程负责看护,回收垃圾。
最起码Java程序中至少有两个线程并发,一个是垃圾回收线程,一个是执行main方法的主线程
3.进程和线程是什么关系?
进程A和进程B的内存独立不共享 线程A和线程B 在Java语言中,堆内存和方法区内存共享, 可是栈内存独立,一个线程一个栈。 假设启动10个线程,会有10个栈空间,每一个栈和每一个栈之间,互不干扰。 Java之因此有多线程机制,目的就是提升程序的处理效率。 4.使用多线程机制以后,main方法结束,是否是有可能程序没结束 5.对于单核的CPU来讲,真的能够作到真正的多线程并发吗? 什么是真正的对线程并发? t1线程执行t1的。 t2线程执行t2的。 t1不会影响t2,t2也不会影响t1,这叫真正的多项成并发。 单核CPU表示只有一个大脑, 不可以作到真正的多项成并发,可是能够作到给人一种"多线程并发"的感受。 对于单核CPU来书,在某一个时间点只能处理一件事请,可是因为CPU的处理速度极快。 多个线程之间频繁切换执行,给人感受是多个事请同时在作。 6.Java语言中,实现多线程有两种方式,哪两种方式呢? 第一种方式:编写一个类,直接继承java.lang.Thread,重写run方法。 //定义线程类 public class MyThread extends Thread{ public void run(){ } } //建立线程对象 MyThread t =new MyThread(); //启动线程 t.start(); 第二种方式:编写一个类,实现java.lang.Runnable接口,实现run方法。 //定义一个可运行的类 public class MyRunnable implements Runnable{ public void run(){ } } //建立线程对象 Thread t =new Thread(new MyRunnable()); //启动线程 t.start();
============================================================
//匿名内部类
Thread t =new Thread(new Runnable() {
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println(“分支线程”+i);
}
}
});
t.start();
~多线程的三种方式 继承Thread 实现Runable 实现Callable ~多线程的生命周期 ~线程的调度(sleep、yield...) ~线程的安全(重点) ~定时器/定时任务 ~守护线程 ~wait方法和notify方法,生产者和消费者模式 24小时多线程笔记: 1 线程概述 1.1 线程相关概念 进程 进程(Process)是计算机中的程序关于某数据集合上的一次运行活动, 是操做系统进行资源分配与调度的基本单位。 能够把进程简单的理解为正在操做系统中运行的一个程序。 线程 线程(thread)是进程的一个执行单元。 一个线程就是进程中一个单一顺序的控制流,进程的一个执行分支。 进程是线程的容器,一个进程至少有一个线程,一个进程也能够有多个线程。 在操做系统中是以进程为单位分配资源,如虚拟存储空间,文件描述符等。 每一个线程都有各自的线程栈,本身的寄存器环境,本身的线程本地存储。 主线程与子线程 JVM启动时会建立一个主线程,该主线程负责执行main方法,主线程就是运行main 方法的线程 Java中的线程不孤立,线程之间存在一些联系,若是在A线程中建立B线程,称B线程为A线程的子线程,相应的A线程就是B 线程的父线程。 串行,并发与并行 串行(Sequential)先作任务A,完成以后在作任务B,完成以后再作任务C ,全部的任务逐个完成。 并发(Concurrent)先开始作任务A,在等待A完成的这段时间内开始作任务B,在等待B完成的时候作任务C.任务交替完成的。 并行(Parallel),三个任务同时开始。总耗时取决于须要时间最长的那个任务。 并发能够提升事物的处理效率,即在一段时间内能够处理或者完成过呢更多的事请。 并行是一种更为严格,理想的并发。 从硬件角度来讲,若是单核CPU,一个处理器一次只能执行一个线程的状况下,处理器可使用时间片轮转技术,可让CPU快速的在各个 线程之间切换,对于用户来讲,感受三个线程在同时执行,若是是多核CPU,能够为不一样的线程分配不一样的内核。 1.2 线程的建立与启动 在Java中建立一个线程就是建立一个Thread类(子类)的对象(实例)。 Thread类有两个经常使用的构造方法:Thread()与Thread(Runnabled)对应的建立线程的两种方式。 定义Thread类的子类 定义一个Runnable接口的实现类 这两种建立线程的方式没有本质的区别。 1.3 线程的经常使用方法 1.currentThread()方法 Thread.currentThread()方法能够得到当前线程 Java中的任何一段代码都是执行在某个线程当中的,执行当前代码的线程就是当前线程。 同一段代码可能被不一样的线程执行,所以当前线程是相对的,这个方法的返回值是在代码实际运行的 时候线程对象, 2.setName()/getName() thread.setName(线程名称),设置线程名称 thread.getName()返回线程名称 经过设置线程名称,有助于程序调试,提升程序的可读性,建议为每一个线程都 设置一个可以体现线程功能的名称。 3.isAlive() thread.isAlive()判断当前线程是否处于活动状态 活动状态就是线程已启动而且还没有终止。 4.sleep() Thread.sleep(毫秒数):当前线程睡眠多少毫秒 当前线程指的是:Thread.currentThread()返回的线程 注意:子线程的run()方法中异常只能捕获处理,而不能上抛,由于父类的run方法没有抛出异常。 5.getId() thread.getId():能够得到线程的惟一标识 注意: 某个编号的线程运行结束后,该编号可能被后续建立的线程使用 重启的JVM后,同一个线程的编号可能不同 6.yield() Thread.yield()方法的做用是放弃当前的CPU资源, 线程让步,放弃CPU的执行权。 7.setPriority() thread.setPriority(num);设置线程的优先级 Java线程的优先级取值范围是1~10,若是超出这个范围会抛异常IllegalArgumentException. 在操做系统中,优先级较高的线程得到CPU的资源越多 线程优先级本质上只是给线程调度器一个提示信息,以便与调度器决定先调度哪些线程,注意不能保证优先级高的线程先运行。 Java优先级设置不当或者滥用可能会致使某些线程永远没法获得运行,即产生了线程饥饿。 线程的优先级不是设置的越高越好,通常状况下使用普通的优先级便可,即在开发时没必要设置线程的优先级。 8.interrupt() 中断线程. 注意调用interrrupt()方法仅仅是在当前线程打一个中止标志,并非真正的中止线程。 isInterrupted() 该方法能够返回线程的中断标志。 9.setDaemon() java中的线程分为用户线程与守护线程 守护线程是为其余线程提供服务的线程,如垃圾回收器(GC)就是一个典型的守护线程。 守护线程 不能单独运行,当JVM中没有其余用户线程,只有守护线程时,守护线程会自动销毁,JVM会退出。 注意:设置守护线程应该在start()以前。 1.4 线程的生命周期 线程的生命周期是线程对象的生老病死,即线程的状态。 线程生命周期能够经过getState()方法得到,线程的状态是 Thread.State 枚举类型定义的,由如下几种: NEW ,新建状态,建立了线程对象,在调用start()启动以前的状态; RUNNABLE,可运行状态。它是一个复合状态,包含:READY 和RUNNING两个 状态,READY状态该线程能够被线程调度器进行调度使它处于RUNNING状态,RUNNING状态表示该线程正在执行。 Thread.yield()方法能够把线程由RUNNING状态转换为READY状态。 BLOCKED,阻塞状态,线程发起阻塞的I/O操做,或者申请由其余线程占用的独占资源,线程会转为BLOCKED阻塞状态, 处于阻塞状态的线程不会占用CPU资源。当阻塞I/O执行完,或者线程得到了其申请的资源,线程能够转换为RUNNABLE。 WAITING,等待状态。线程执行了object.wait(),thread.join()方法会把线程转换为WAITING等待状态,执行object,notify()方法, 或者加入的线程执行完毕,当前线程会转换为RUNNABLE状态。 TIMED_WAITING,状态与WAITING状态相似,都是等待状态,区别在于处于该状态的线程不会无限的等待,若是线程没有在指定的时间范围内完成指望的操做, 该线程自动转换为RUNNABLE TERMINATED,终止状态,线程结束处于终止状态。 1.5多线程编程的优点与存储的风险 多线程编程具备如下优点: 1)提升系统的吞吐率(Throughout)。多线程编程可使一个进程有 多个并发(concurrent),即同时进行的操做。 2)提升响应性(Responsiveness)。Web服务器会采用一些专门的线程 负责用户的请求处理,缩短了用户的等待时间 3)充分利用多核(Multicore)处理器资源,经过多线程能够充分的利用CPU资源 多线程编程存在的问题与风险: 1)线程安全(Thread safe)问题。多线程共享数据时,若是没有采起争取的 并发访问控制措施,就会产生数据一致性问题,如读取脏数据(过时的数据) 如丢失数据更新。 2)线程活性(Thread liveness)问题。因为程序自身的缺陷或者有资源稀缺性致使线程 线程一直处于非RUNNABLE状态,这就是线程活性问题,常见的活性故障有如下几种: (1)死锁(Deadlock),相似于鹬蚌相争。 (2)锁死(Lockout),相似于睡美人 故事中王子挂了, (3)活锁(Livelock),相似于小猫咬本身尾巴 (4)饥饿(Starvation),相似于健壮的雏鸟老是从母鸟嘴中抢到食物 3)上下文替换(Context Switch)处理器从执行一个线程切换到执行另一个线程 4)可靠性 可能会有由一个线程致使JVM意外终止,其余的线程也没法执行 2 线程安全问题 非线程安全主要是指多个线程对同一个对象的实例变量进行操做时, 会出现值被更改,值不一样步的状况。 线程安全问题表现为三个方面:原子性、可见性和有序性 2.1原子性 原子(Atomic)就是不可分割的意思。原子操做的不可分割有两层含义: 1)访问(读、写)某个共享变量的操做从其余线程来看,该操做要么已经执行完毕 ,要么还没有发生,其余线程看不到当前操做的中间结果。 2)访问同一组共享变量的原子操做是不可以交错的, Java中有两种方式实现原子性:一种是使用锁;另外一种利用处理器的CAS(Compare And Swap)指令 锁具备排他性,保证共享变量在某一时刻只能被一个线程访问, CAS指令直接在硬件(处理器和内存)层次上实现,看做是硬件锁。 2.2可见性 在多线程环境中,一个线程对某个共享变量进行更新以后,后续其余的线程可能没法当即读到这个更新的结果,这就是线程安全问题的 的另外一种形式:可见性(visibility) 若是一个线程对共享变量更新后,后续访问该变量的其余线程能够读到更新的结果,称这个线程对共享变量的更新对其余线程可见,不然称这个 线程对共享变量的更新对其余线程不可见。 多线程程序由于可见性问题可能会致使其余线程读到了旧数据(脏数据)。 2.3有序性 有序性(Ordering)是指在什么状况下一个处理器上运行的一个线程所执行的,内存访问操做在另一个处理器运行的其余线程看来是乱序的(Out of Order). 乱序是指内存访问操做的顺序看起来发生了变化 在多核处理器的环境下,编写的顺序结构,这种操做执行的顺序多是没有保障的; 编译器可能会改变两个操做的前后顺序; 处理器也可能不会按照目标代码的顺序执行; 这种一个处理器上执行的多个操做,在其余处理器来看它的顺序于目标代码指定的顺序可能不同, 这种现象称为重排序。 重排序是对内存访问有序操做的一种优化,能够在不影响单线程的程序正确的状况下提高程序的性能,可是可能对多线程程序的 正确性产生影响,便可能致使线程安全问题。 重排序与可见性问题相似,不是必然出现的。 与内存操做顺序有关的几个概念: 源代码顺序,就是源码中指定的内存访问顺序。 程序顺序,处理器上运行的目标代码所指定的内存访问顺序 执行顺序,内存访问操做在处理器上的实际执行顺序。 感知顺序,给定处理器所感知到的该处理器及其余处理器的内存访问操做的顺序 2.4Java内存模型
10.第十章 反射机制
1.反射机制有什么用?
用过Java语言中的反射机制能够操做字节码文件。
能够读和修改字节码文件
经过反射机制能够操做代码片断(class文件)
2.反射机制相关的类有哪些?
java.lang.Class :表明整个字节码,表明一个类型
java.lang.reflect.Method:表明字节码中的方法字节码
java.lang.reflect.Constructor:表明字节码中的构造方法字节码
java.lang.reflect.Field:表明字节码中的属性字节码。
//java.lang.class public class User{ //Field int no; //Constructor puclic User(){ } //method public void setNo(int no){ this.no=no; } public int getNo(){ return no; } } ~获取Class的三种方式 第一种方式: Class.forName() 1.静态方法 2.方法的参数是一个字符串/ 3.字符串须要的是一个完整类名 4.完整类名必须带有包名。java.lang包也不能省略。 例: try{ Class c1 =Class.forName("java.lang.String"); //c1表明String.class文件 }catch{ e.printStackTrace(); } 第二种方式: Java中任何一个对象都有一个方法getClass(); 例: String s= "abc"; Class x =s.getClass();//x表明String.class字节码文件 第三种方式: Java语言种任何一种类型,包括基本数据类型,它都有.class 属性 例: Class z =String.class; Class x =Date.class; ~经过反射机制可以实例化对象 反射机制的灵活性: 一次代码,再不改变原来的代码基础上能够作到不一样对象的实例化。 符合OCP原则(对扩展开放,对修改关闭) 重点: 若是只是但愿一个类的静态代码块执行,其余代码不执行, 可使用: Class.ForName("完整类名"); (JDBC 处使用) ~路径: src是类的根路径。 获取路径(采用这种方式能够拿到一个文件的绝对路径) 记住: String path = Thread.currentThread().getContextClassLoader().getResource("").getPath(); ~资源绑定器 java.util包下提供了一个资源绑定器,便于获取属性配置文件中的内容。 属性配置文件xxxx.properties放在类路径下。 ResourceBundle bundle =ResourceBundle.getBundle("文件名不带后缀"); String className =bundle.getString("className"); ~关于JKD自带的类加载器 1.什么是类加载器? 专门负责加载类的命令/工具 ClassLoader 2.JDK中自带了三个类加载器 启动类加载器 扩展类加载器 应用类加载器 3.假设有这样一段代码 String s="abc"; 代码在开始执行以前,会将所须要类所有加载到JVM中, 经过类加载器加载,看到以上代码类加载器会找String.class 文件,找到就加载,那么是怎么进行加载的呢? 首先经过"启动类加载器"加载 注意:启动类加载器专门加载rt.jar核心的类库 若是找不到,那么扩展器扩展类 扩展器没有找到,经过应用类加载器加载 ~反射Filed,操做Field ~反射Method,操做Method ~反射Constructor,操做Constructor ~经过反射机制获取父类,以及获取父接口 ~可变长参数: int...args
/*可变长度参数
1.可变长度参数要求是类型…(必定是三个…)
2.参数个数0-N个
3.可变长度参数必定在最后位置,而且只能由一个
*/
public class args {
public static void main(String[] args) {
fun(3);
fun(10,30);
fun(1,2,3,4);
m1(“hello”);
m1(“zhangsan”,“nihao”);
m1(“a”,“b”,“c”,“d”);
}
public static void fun(int …args){
System.out.println(“fun方法执行了”);
}
public static void m1(String …args){
//args属性有length说明是一个数组 也能够传一个数组
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
}
}
}
11.第十一章 注解
~怎么自定义注解?
1.注解,或者叫作注释类型,英文单词是:Annotation
2.注解Annotation是一种引用数据类型。编译以后也是生成xxx. class文件。
3.自定义注解?语法格式?
[修饰符列表]@interface 注解类型名{
} 4.注解使用语法格式是: @注解类型名 注解能够出如今类上、属性上、方法上、变量上、注解上 5.JDK自带哪些注解? 标识性注解 @Override 这个注解只能注解方法,这个注解是给编译器参考的,和运行阶段没有关系。 凡是Java中的方法带有这个注解的,编译器都会进行编译检查,若是这个方法不是重写父类的方法,编译器报错。 表示方法声明旨在覆盖超类型中的方法声明。 API帮助文档介绍: 若是使用此注释类型注释方法,则除非至少知足如下条件之一,不然须要编译器生成错误消息: 该方法将覆盖或实如今超类型中声明的方法。 该方法具备与Object中声明的任何公共方法的覆盖相同的签名 。 Deprecated 用@Deprecated 注释的程序元素,不鼓励程序员使用这样的元素,一般是由于它很危险或存在更好的选择(已过期)。 ~元注解有哪些? 元注解:用来标注“注解类型”的注解,称为元注解。 常见的元注解 Target 表示"被标注的注解位置只出如今哪一个位置上" Retention 表示"被标注的注解"最终保存在哪里。 @Retention(RetentionPolicy.SOURCCE):表示该注解只能被保留在Java源文件中。 @Retention(RetentionPolicy.RUNTIME):表示该注解能够被反射 @Retention(RetentionPolicy.CLASS):表示该注解被保存在class 文件中,而且能够保留在字节码文件中 ~ 注解的属性是value 有且只有一个时,能够省略value =; 其余状况不行 注解中的属性能够是哪一种类型? byte short int long double boolean char String Class 枚举类型 (以上的数组形式) 数组中只有一个元素,大括号能够省略。 ~经过反射机制读取注解? ~了解注解的实现原理以及应用?