JAVASE
1:java代码的执行:第一步:写好源代码,保存为.java后缀的文件
第二步:利用工具将.java文件编译为.class后缀的文件
第三步:将.class文件解释执行
2:class命名规范:名字只能含有字母、数字、_、$和中文。数字不能开头。类名首字母最好大写,
多个单词首字母都最好大写。
3:变量命名规范:名字只能含有字母、数字、_、$和中文。数字不能开头。
如果有多个单词,首字母小写,之后的首字母都最好大写。
4:数据类型:一:基本数据类型(8个)
1:byte(字节型) ---- 1字节 ---- 8bit ---- -2的7次方到2的7次方-1
2:short(短整形) ---- 2字节 ---- 16bit
3:int(整形) ---- 4字节 ---- 32bit
4:long(长整形) ---- 8字节 ---- 64bit
5:float(浮点型,单精度) ---- 32bit ---- 4字节
6:double(浮点型,双精度) ---- 64bit
7:char(字符) 2字节 16bit
8:boolean(布尔型)---- 1bit
二:引用数据类型
1:[](数组)2:class(类)3:interface(接口)
4:enum(枚举)5:注解(@interface)6:字符串
5:变量:int num = 1;
num是变量,存在栈内存里(先进后出)
1是值,存在常量缓存区
=将存在常量缓存区里的1复制一份给num
6:类型转换:一 整形之间的转换
(1)如果是把小字节的类型转换为大字节的类型,系统自动帮你转
(2)如果是把大字节的类型转换为小字节的类型,需要手动转(强制类型转换)(要注意数据类型的范围)
例1(正常转换) int a = 2;
byte b = (byte)a
例2 int a = 1000; byte b = (byte)a
因为byte最高只能表示127,将a强制转换为byte类型后,计算机会砍掉一部分
计算机会先将1000转换为2进制,然后砍掉24个bit,然后转换为10进制。这样的话,转换之后的数会和原先的数相差甚远。
二 整形和浮点型的转换:
整形和浮点型比较的是精确程度,浮点型比所有整形的精确程度都高,所以可以直接存放整数,反之需要强制转换,会砍掉小数部分。
三 char类型和int之间的转换
char转int:计算机会先将字符转换为对应的Unicode码,然后转为数字
int转char:先将数字转为Unicode码对应的字符,然后转为char
7:递增递减:
例:int x = 2;
x = x ++; //x是2
x在想要做值交换的时候,会产生一个临时的副本空间(备份)。++在变量的前面,先自增后备份。++在变量的后面,先备份后自增。赋值是赋的副本空间备份好的值
8:+=(-=):
byte num = 1;
num = num + 2;//结果会报错
原因:num是byte类型的,8bit的容量。2是常量池里的,是32bit的。相加时首先会自动将要进行计算的num转换为32bit的容量,然后计算。赋值时因为左边的num是8bit的容量,所以想赋值必须进行强制类型转换。(byte)(num + 2)
9:JAVA中布尔值是不能进行类型转换的
10:运算类型:(1)单目运算 a++
(2)双目运算 a + b
(3)三目运算 a > b ? c : d
11:逻辑运算符: 1 -- &(逻辑与)前后2个条件都为true时,结果为true,否则结果为false
2 -- | (逻辑或)2个条件只要有一个条件成立,结果就为true,否则结果为false
3 -- !(逻辑非)单目运算。条件为真,结果就是假。条件为假,结果就是真
4 -- ^(逻辑异或)2个条件一真一假时,结果为true,否则结果为false
5 -- &&(短路与): &&和&功能一样,但是在某些情况下性能会好点
短路的是&&之后的所有计算过程,如果左边的条件为false,那么右边的条件表达式不会执行,从而提升效率
&&和&的区别:当左边条件为false时,最终结果已经确定为false,右边的表达式已经没有意义。但&仍然会执行右侧表达式,而&&不会执行。节省性能。
6 -- || (短路或):|| 和 | 功能一样,但是在某些情况下性能会好点
短路的是 || 之后的所有计算过程,如果左边的条件为true,那么右边的条件表达式不会执行,从而提升效率
&&和&的区别:当左边条件为true时,最终结果已经确定为true,右边的表达式已经没有意义。但 | 仍然会执行右侧表达式,而 || 不会执行。节省性能。
12:进制转换(计算机组成原理的知识,并非JAVA独有): 计算机只能识别2进制数 0是断电,1是通电
10进制转2进制:10进制数除2的余数倒排并补零 177 -> 10110001 java中整形是32bit,所以要补全到32个bit,补全24个0
2进制转10进制:从最右边位开始,每一个数乘2的位置(0开始)次幂,最终求和
2进制转换为8进制:从最右边开始,每三位一组,将它们转换为10进制。8进制前面要加一个0来和其他进制区分
例:177 -> 0261
2进制转换为16进制:从最右边开始,每四位一组,将它们转换为10进制。8进制前面要加一个0X来和其他进制区分
例:177 -> 0XB1 每四位一组转换后如果是一位,那么不变,如果是2位,那用字母代替,不区分大小写,一致即可。 10 -> A 11 -> B 以此类推,直到15 -> F
13:位运算:3 & 5 3 | 5 3 ^ 5 ~5
计算步骤:1 -> 将3和5都转换为2进制
2 -> 竖着按照对应位置进行 & | ^ 来计算
3 -> 将计算后的值转换为10进制
~5就是求补码
<<:按位左移 >>按位右移 >>>按位右移(无符号)
例:6<<2 == 24 (将6转换为2进制,整体向左移动2位,右边空位补零)
6>>2 == 1(将6转换为2进制,整体向右移动2位,左边补零)
-6>>>2 == -1(将-6转换为2进制,整体向右移动2位,左边第一位补1,然后补0)
14:原码、反码、补码(二进制数以左边第一位表示正负,0是正,1是负):
177 -177
原码:00000000 00000000 00000000 10110001 10000000 00000000 00000000 10110001
反码:00000000 00000000 00000000 10110001 11111111 11111111 11111111 01001110
补码:00000000 00000000 00000000 10110001 11111111 11111111 11111111 01001111
原码:原码就是正常的二进制数
反码:正数的反码和原码一样,负数的反码是符号位不变,其余位取反
补码:正数的补码和原码一样,负数的补码是反码加1
注意:计算机中不管正数还是负数,存储的都是补码
15:随机数 Math.random() //产生一个0.0到0.999...之间的左闭右开的小数,通过数学运算可以控制它的取值范围
(int)(Math.random() * 6 + 1) //将范围控制在1到6之间
16:字符串比较 因为字符串是引用类型,通过 == 比较的是地址,所以永远不会相等。若要比较字符串的值是否一样要用.equals()方法
17:增强for循环:
int[] array = {12,33,22,1};
for(int item : array) {
System.out.println(item)
}
//打印 12 33 22 1
增强for循环和普通for循环的使用:如果只是遍历输出的话用增强型的方便,如果要对每一项都进行其他操作的话用普通的好
18:数组默认值:
整形:0 浮点型:0.0 boolean型:false 字符型:0所对应的字符,是不可见的 引用类型:null
19:如果一个引用类型的变量在接下来不再使用,那么可以给它赋值为null,将变量和数据地址的联系断开。会有GC(垃圾回收机制)清理掉这些数据,释放内存空间。
20:重载:相同的方法但是参数不同就是重载,通过传参的不同自动选择对应的方法
参数列表的不同:
1. 参数的个数不同(容易理解)
2. 参数的类型不同(举例说明,参数个数相同,但是类型不同,也叫做参数列表的不同)
3. 参数的多类型顺序不同(举例 先double,后int,然后先int,后double)
重载与以下因素无关:
1. 与返回值无关(举例)
2. 与参数的名称无关
21:继承:
1.子类可以继承父类中非私有的属性和方法,可以当做自己的来使用.
2.父类中定义的非私有成员都是子类共有的成员.
3.Java中一个子类只能有一个父类,只能单继承.不过支持多层基层
4.如果子类中定义了与父类中同名的属性和方法,通过子类对象访问这些属性和方法时,访问的是子类中定义的这些属性和方法.
22:重写:
在子类中定义了一个与父类中一模一样的方法(方法名和参数列表一样);
23:重写(Override)跟重载(Overload)的区别:
1. 重载是在一个类中出现的方法名称一样,参数列表不一样的情况
2. 重写(覆盖)是出现在子类和父类中的重名方法,在使用子类对象调用该方法的时候,最终执行的是子类重
24:子类构造器中调用父类构造器的特点:
1. 子类的每个构造方法中,都默认调用了父类中的无参的构造方法,默认执行了"super();",即使自己没有调用,系统也默认赠送一个无参的构造方法.
2.在子类的构造方法中如果手动调用父类中的构造方法,系统就不再赠送那个无参的构造方法了.
3.在子类的构造方法中,只能调用一次父类的构造方法,而且只能写在第一个语句的位置.
25:super关键字的三种用法
1.在子类的成员方法中,可以通过super访问父类中定义的成员变量、成员方法、构造方法;
26:this关键字的三种用法
1.在本类的成员方法中,可以通过this访问本类中成员变量、成员方法、构造方法;
27:抽象类的概念:
抽象类:不是一个具体类,不能创建对象;
如果一个类中包含的有抽象方法,这个类就是抽象类.
28-抽象方法和抽象类的使用
步骤:
1.定义子类继承抽象父类;
2.在子类中实现抽象父类中定义的抽象方法;
3.创建子类对象,通过子类对象访问抽象父类中定义的成员和被重写的方法;
29-抽象方法和抽象类的注意事项:
注意事项:
1.抽象类不能创建对象;
2.如果类中定义了抽象方法,这个必须定义成抽象类;
3.抽象类中可以没有抽象方法;
4.子类中必须实现抽象父类中所有的抽象方法,否则必须把子类也定义成抽象类;
30-接口与抽象类的区别
1.接口中可以定义:
常量
抽象方法
私有方法
静态方法
默认方法
2.抽象类中可以定义:
常量
变量
成员方法
静态方法
私有方法
3.抽象类
不能定义默认方法;
只能作为父类使用,让子类继承;
4.接口
可以定义默认方法
不能定义成员变量
不能定义成员方法
接口需要定义实现类
31:通过多态调用成员的注意事项:
1:只能调用父类有的方法属性,不能调用子类独有的方法
32:instanceof关键字:
用来判断对象是哪个类的
33:static:
静态变量可以被所在类所有的对象共享
34:异常的概述和异常体系
1. 异常:是指程序出现了不正常的情况
例如:代码演示一个整数除以0,则程序会出现ArithmeticException异常
(通过API说明)ArithmeticException:当出现异常的运算条件时,抛出此异常。例如,一个整数“除以零”时,抛出此类的一个实例。
(Java中的异常有很多,但是所有异常的父类都是Throwable)
Throwable 类是 Java 语言中所有错误或异常的超类。
Error 是 Throwable 的子类,用于指示合理的应用程序不应该试图捕获的严重问题。
如果程序发生了Error错误,那么Java语言是无法解决的,比如说硬件层面的问题。
Exception 类及其子类是 Throwable 的一种形式,它指出了合理的应用程序想要捕获的条件。
如果成员发生了Exception异常,我们就需要去处理一下。
(Exception异常也可以分成两种情况)
RuntimeException 是那些可能在 Java 虚拟机正常运行期间抛出的异常的超类。
运行期的异常:在编译期不做任何处理,在程序运行的时候出现了问题。
35:DateFormat类中的format方法
练习一:把Date对象转换成String
Date date = new Date(1607616000000L);//Fri Dec 11 00:00:00 CST 2020
DateFormat df = new SimpleDateFormat(“yyyy年MM月dd日”);
String str = df.format(date);
//str中的内容为2020年12月11日
36-DateFormat类中的parse方法
练习二:把String转换成Date对象
String str = ”2020年12月11日”;
DateFormat df = new SimpleDateFormat(“yyyy年MM月dd日”);
Date date = df.parse( str );
//Date对象中的内容为Fri Dec 11 00:00:00 CST 2020
37-Calendar类介绍_获取对象的方式
Calendar是通过getInstance()方法来获取对象,而不是像之前那样new对象
38-Calendar类常用的方法
abstract void add(int field, int amount) : 增加偏移量,修改时间.
int get(int field): 获得当前时间的时间字段值.
int getFirstDayOfWeek() :获得一周中第一天;
Date getTime() : 获得当前日历时间对应的Date数据.
long getTimeInMillis() :获得当前时间距离 1970年1月1日 00:00:00 的毫秒数;
void set(int field, int value) 将给定的日历字段设置为给定的值。
39:String:
String对象的两种创建方式:
1:String str = new String("李辉"); 每new一个字符串对象,都会在堆内存中,开辟一块空间用来存方法字符串,然后把地址给引用
2:String str = "李辉";直接赋值,则先在堆内存中再开辟空间 保存hello,然后再常量池中开辟一块空间来保存堆空间的地址,然后每次只要是直接赋值就会先看看堆内存有没有这个值, 只要有。就会重复使用,
40-StringBuilder和String的相互转换(StringBuilder在字符串拼接上比String更有效率)
1. 下面我们写个练习:StringBuilder跟String之间的相互转换
StringBuilder ---> String
使用toString()
String ----->StringBuilder
使用StringBuilder的有参构造
41-集合体系结构介绍
1. 集合最主要的功能就是存储和取出数据
2. 集合分为单列集合和双列集合
2.1 单列集合:集合中的每一个元素都是单一的。跟数组一样。
2.2 双列集合:集合中的每一个元素都是由两部分组成。key-value 键和值
3. 根据 "元素是否可以重复" "是否有序" 可以把单列集合Collection分为
List集合:元素可重复。 有序(存储元素的顺序跟取出元素的顺序一致)。
Set集合:元素不能重复。无序(不能重复是基于重写equals方法,自定义对象要重写equals方法才能实现不能重复的效果)
4. List接口的实现类有:ArrayList(底层是基于数组实现的,查询快,增删慢) 、LinkedList(底层基于链表实现,查询慢,增删快)
Set接口的实现类有:HashSet
Map接口的实现类有:HashMap
5.Collection集合是单列集合的顶层接口。
42:list集合的遍历有三种:
1:创建迭代器对象配合while进行遍历
Iterator<Student> it = linkedList.iterator();
while(it.hasNext()) {
Student stu = it.next();
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge());
}
2:使用增强for循环进行遍历
3:通过get方法配合普通for循环进行遍历
43:Set集合遍历不能用普通for遍历,因为它是无序的,没有索引
44:Map集合的遍历:
1:将key值存到set集合里,然后利用key值获取value
Set<String> set = map.keySet(); //将map的所有key值存在set集合中
2:利用增强for循环遍历,遍历类型为Map.Entry<>类型,Map.Entry<>是存放key和value的容器。通过这个容器的getKey和getValue取值。
45:Collections工具类常用方法(操作集合的一些工具):
shuffle(List<?> list):将传入的集合成员位置打乱
sort(List<?> list):将集合中的成员按照升序排列
46:泛型:
泛型用来灵活地将数据类型应用到不同的类、方法、接口当中。将数据类型作为参数传递。
泛型是数据类型的一部分,我们将类名与泛型合并一起看做数据类型。
泛型的定义:定义泛型可以在类中预支地使用未知的类型。
泛型的使用:一般在创建对象时,将未知的类型确定具体的类型。当没有指定泛型时,默认类型为Object类型。
47:泛型的好处:
将运行时期的ClassCastException,转移到了编译时期变成了编译失败。
避免了类型强转的麻烦。
1:含有泛型的类:
定义格式:修饰符 class 类名<代表泛型的变量> { }
使用格式:创建对象时,确定泛型的类型
例如,ArrayList<String> list = new ArrayList<String>();
2:含有泛型的方法:
定义格式:修饰符 <代表泛型的变量> 返回值类型 方法名(参数){ }
使用格式:调用方法时,确定泛型的类型
3:含有泛型的接口:
定义格式:修饰符 interface接口名<代表泛型的变量> { }
1、定义类时确定泛型的类型
2、始终不确定泛型的类型,直到创建对象时,确定泛型的类型
线程相关知识:
1:线程的创建方式:
(1):将类声明为 Thread 的子类。该子类应重写 Thread 类的 run 方法。创建对象,开启线程。run方法相当于其他线程的main方法。
(2):声明一个实现 Runnable 接口的类。该类然后实现 run 方法。然后创建Runnable的子类对象,传入到某个线程的构造方法中,开启线程。
2:通过继承实现的线程和通过接口实现的线程有什么区别?哪个好?
继承只能单继承,接口却能多实现
3:线程的安全问题:
线程安全问题都是由全局变量及静态变量引起的。若每个线程中对全局变量、静态变量只有读操作,而无写操作,一般来说,这个全局变量是线程安全的;若有多个线程 同时执行写操作,一般都需要考虑 线程同步,否则的话就可能影响线程安全。
4:线程同步:
(1):将可能引发bug的代码放在synchronized ()代码块里面执行,方法需要一个对象(任意对象都行,但不可更改)
(2):将可能引发bug的代码放在由synchronized修饰的方法里调用
(3):通过lock锁实现代码同步
5:什么是进程?
进程:进程指正在运行的程序。确切的来说,当一个程序进入内存运行,即变成一个进程,进程是处于运行过程中的程序,并且具有一定独立功能。
6:什么是线程?
线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程。一个进程中是可以有多个线程的,这个应用程序也可以称之为多线程程序。
简而言之:一个程序运行后至少有一个进程,一个进程中可以包含多个线程
多线程程序并不能提高程序的运行速度,但能够提高程序运行效率,让CPU的使用率更高。
7:程序运行原理
分时调度:所有线程轮流使用 CPU 的使用权,平均分配每个线程占用 CPU 的时间。
? 抢占式调度:优先让优先级高的线程使用 CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),Java使用的为抢占式调度。
8:常用方法:
(1)start() 启用线程
(2)Threaad.sleep() 休眠
(3)interrupt() 手动停止线程
(4)wait() 等待
9:sleep()和wait()的区别
sleep()表示线程休眠,只有休眠结束后才会进入运行或者受阻塞状态
wait()表示等待,只有调用notify或者notifyAll()方法才会结束等待,进入运行或者受阻塞状态
I/O(输入输出流)知识点:
(1):什么是文件?
一种电脑的存储形式
文件有不同的格式 .txt .doc .ppt .jpg .mp3...
(2):File类:文件或目录的抽象表示形式的一个类
(3):