java体系平台
- JavaSE 标准版 像开发360,百度网盘
- JavaEE 企业版
- JavaME
JDK=JRE+开发工具集 JRE=JVM+JAVA SE API(即JavaSE标准类库
常用基本命令行
- 更改盘符 d:
- 打开文件 cd 路径
- 查看文件目录 dir
- 新建文件夹 md name
- 退回上一级 cd..
- 删除文件夹 rd name
- 删除文件 del name
注释
Java特有文档注释
可以被javadoc解析 生成一个以网页形式出现的文件,页面效果类似JavaAPI文档说明1.Java编译过程
1.编写
创建一个HELLOWORLD.java文件
class HELLOCHIMA{
}
2.编译
javac HELLOWORLD.java
3.运行
java HELLOCHINA
2.Java命名规范
包名:所有字母都小写
类名,接口名:所有单词的首字母大写
变量名,方法名:第一个单词首字母小写,后面的单词首字母大写
常量名:所有字母都大写,每个单词用下划线连接
3.Java数据类型
基本数据类型
整型:byte(1)、short(2), int(4), long(8,long型变量必须以大写L或者小写l结尾)
浮点型:float(4,7位小数,后面必须加F或f,表示范围比long还大), double(8,14位小数)
字符型:char(2)
布尔型:boolean
引用数据类型
类(class)
接口(interface)
数组(array)
自动类型提升
byte,short,char—–>int——->long——>float——->double
当byte,short,char三种进行运算时,结果都为int
强制类型转化
可能会导致精度损失
string类
不可以有子类,String常量放入常量池(常量池中的数据在运行期间在也不允许改变)
- equals:比较的是值
- startsWith(String s)//判断当前String对象的字符序列前缀是否含有s的字符
- endsWith(String s)
- str1.compareTo(“s2”)//s1与s2比较
- s1.contains(“s2”)
- Arrays.sort(b)
- getChars(int start,int end,char,int offset)
字符串类型。引用数据类型 ,拼接运算+
system.out.println(‘a’+’/t’);//输出107
system.out.println(‘a’+“/t”+’a’);//输出a a
String与StringBuffer
1.二进制 0b或者0B
2.八进制 0开头
3.十进制
4.十六进制 0x或者0X
正数的原码,补码,反码一样
正数的符号位是0,负数的符号位是1
负数
反码:在原码的基础上,符号位不变,其余取反
补码:在反码的基础上加一
计算机底层都是补码的形式
4.Java运算符
算术运算符
/除
整除
1
2
3
4
5
6
7double a = 3; double b = 2;
double c = a / b; //1.0不是1.5
double c = a / ( b + 0.0 ); //是1.5
double c = ( double ) a / b; //是1.5%取模
取模的符号和被模数的符号是一样的
前++
1
2
3
4
5
6
7先自增再运算
int a = 1;
int b = ++ a;
//a=2,b=2后++
1
2
3
4
5
6
7先运算后自增
int a = 1;
int b = a ++;
//a=2,b=1注意:单独写a++;++a的时候效果一样,并且自增自减不会改变原数据类型
赋值运算符
下面这些不会改变数据类型
short a = 1;
a += 1;//相当于a = a + 1;但是不会像它一样报错,会编译通过
+=
%=
/=
-=
比较运算符
结果为boolean型
==
!=
逻辑运算符
只适用于boolean型的运算
&与
&&短路与
相同点1:&与&&的运算结果相同
相同点2:当符号左边为ture,都会执行符号右边的运算
不同点:当符号左边为false,&会继续执行符号右边,&&短路不再执行右边的运算
如:遇到&&就停止
1
2
3
4
5
6b2 = false;
num = 1;
b2 && ( num++ );
//num = 1;
b2 & ( num ++);
//num = 2;
- |或
- ||短路或
相同点1:|与||的运算结果相同
相同点2:当符号左边为false,都会执行符号右边的运算
不同点:当符号左边为true,&会继续执行符号右边,&&短路不再执行右边的运算
- !非
- ^异或
位运算符(整形数据)
- << 左移 每次向左移一位就是乘以2(在一定范围内)
>>
右移 每向右移一位除以2(在一定范围内)>>>
无符号右移- & 与
- | 或
- ~ 取反 包括符号位在内取反,6取反就是-7
- ^ 异或
注意:都是在二进制的基础上进行移位
三元运算符
要求表达式1与表达式2的类型一致
如果既能用三元又能用if语句,推荐使用三元。因为三元的运算效率更高更简洁。
运算符优先级
没必要记住,想优先加小括号
有一个Java认证叫OCJP
break和continue
break 结束当前循环
continue 结束当次循环
注意:2个关键字的后面不能声明执行语句
5.数组
数组本身是引用数据类型,数组元素可以是基本数据类型或者引用类型
初始化
静态初始化:数组的初始化和数组的赋值操作同时进行
ids = new int[]{1001,1002,1003};
动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
必须声明长度,一旦确定就不可修改
二维数组
1 | 静态初始化 |
初始化默认值
char型为0或‘\u0000’ 不是’0‘
boolean型为false
数组元素是引用数据类型 默认值为null
数组复制
复制arr1数组给arr2
1 | arr2 = new int[arr1.length]; |
不能直接arr2 = arr1(此为赋值操作);这样给的是地址,arr2修改会影响arr1
数组反序
中间临时变量temp,注意终止条件为小与数组长度的一半
方式二:终止条件为 i < j;循环为i++,j–;
数组查找
- 线性查找
String dest = "AA"; if(dest.equals(arr[i])){System.out.print("找到了")}
- 二分法查找(要求有序数组)
- 哈希
- 差值
- 等等
- 线性查找
6.Eclise快捷键
ctrl shift f 格式化代码,使杂乱的代码整齐
ctrl shift o 一键导入所有包
shift enter 从任意位置跳到下一行
ctrl shift enter 从任意位置将本行跳到下一行,在前面出现一个空行
补全代码的声明 art + /
快速修复 ctrl + 1
批量导包 ctrl + shift + o
选择代码块注释 ctrl + shift +/
取消代码块注释 ctrl + shift +\
复制指定行向上(向下) ctrl + alt + up(down)
删除指定行代码 ctrl + d
上下移动 alt + up(down)
下一行 shift + 回车
上一行 ctrl + shift +回车
查看源码 ctrl + 选中结构 或者 ctrl + shift + t
退回到前(后)一个编辑页面 alt + left (right)
查看继承树 ctrl + t
格式化代码 ctrl + shift + f
整体后移 tab
整体前移 shift + tab
在源码中查看 ctrl + o
批量修改 alt + shift +r
指定小写 ctrl + shift + y
指定大写 ctrl + shift + x
调出构造器 alt + shift + s
显示当前选择资源(工程or文件)的属性 alt + enter
快速查找:选中快速定位到下一个ctrl + k
查看指定的结构使用过的地方 ctrl + alt + g
IDEA快捷键
psvm public static void main(String[] args){}
sout System.out.println()
ctrl+D 向下复制本行代码
alert+回车 快速生成方法
7.流程控制
1.顺序结构
2.分支结构
if else
注意条件表达式之间的关系(互斥,相交,包含) 从而决定书写顺序
switch case
switch结构的表达式,只能是如下的6种数据类型之一:byte,short,char,int,枚举类型(JDK5.0新增),String(JDK7.0新增)
break是可选 不是必需
1.凡是可以用switch-case结构,都可以转化为if-else。反之不成立。
2.优先选用switch-case。因为switch-case效率比if-else高一些
3.循环结构
for
while
for与while可以相互转化
do-while(较少使用,循环体至少执行)
初始条件1;
do{
循环体3;
迭代条件4;
}while(循环条件2);
执行顺序:1–>3–>4–>2
8.scanner
1 | import java.util.Scanner; |
9.Math.random()
- Math 和String,System一样都是一个类,首字母需要大写
- Math.radom()是double类型,且随机数的范围是[0.0,1.0)
1 | //随机产生一个数,范围在【10,99】 |
10.排序
冒泡排序
相邻元素依次比较。比如5个元素会比较4大轮,第一大轮会比较4 次
堆排序
归并排序
快速排序
时间复杂度O(nlog(n))
20世纪十大算法之一
性能
Arrays类
- Arrays.equals(arr1,arr2); //比较数组arr1与arr3
- Arrays.toString(arr1);//输出arr1的信息
- Arrays.fill(arr1,10); //将数组arr1的元素替换为10
- Arrays.sort(arr1);//用快排排序
- Arrays.binarySearch(arr1,10);//在数组arr1中查找10,找到返回索引值,找不到返回负数。
数组中的常见异常
1.数组角标越界异常
2.空指针异常
11.类
- 方法
- 属性
- 构造器(或构造方法,constructor)
属性 = 成员变量 = filed = 域,字段
方法 = 成员方法 = 函数 = method
创建类的对象 = 类的实例 = 实例化类
类和对象的使用
创建类,设计类的成员
创建类的对象
调用属性,方法
*如果创建一个类的多个对象,则每个对象都独立有一套类的属性(非static) *
属性(成员变量) VS 局部变量
- 局部变量没有初始化值,在调用之前一定要显式赋值。
栈(局部变量),堆(new出来的结构:对象,数组)
static变量 VS 实例变量
类变量随对象的加载而加载,实例变量在类创建的时候分配空间
只要权限允许,可以通过“对象.static属性”调用,存在于方法区的静态域,不能使用this,super
类方法(static)与实例方法
对象调用实例方法,类名调用类方法
类中方法的声明和使用
main()方法作为程序的入口
是一个普通的静态方法
作为我们与控制台交互的方式
final
可以修饰类,方法,变量
修饰过的东西不能被其他的东西继承重写static final用来修饰属性:全局属性
abstract
可以修饰类(抽象类),方法(抽象方法)
抽象类:不能被实例化,一定有构造器,便于子类实例化调用
抽象方法:只有方法名,没有方法体
** 包含抽象方法的类一定是抽象类,反之不成立(接口) **
构造器
构造方法:没有类型,用来创建对象的时候使用
作用
①创建对象 new + 构造器
②初始化对象的属性
说明
格式:权限修饰符 类名(形参列表){}
一个类中定义的多个构造器也构成重载
一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
属性赋值的先后顺序
①默认初始化
②显式初始化
③构造器中的赋值
④通过“对象.方法”或“对象.属性”
序号大的会覆盖序号小的
包装类
byte–Byte;short–Short;char–Character;int–Integer;long–Long;float–Float;double–Double
小结:①类是组成java源文件的基本元素,一个源文件由若干个类组成②类有两种重要的成员:成员变量(实例变量,类变量)和方法(构造方法,实例方法,类方法)
内部类
Java中允许将一个类A声明在另外一个类B中,类A就是内部类
命名:B$A匿名类
匿名类一定是内部类,可以继续父类的方法也可以重写。类体内不能声明static成员变量和static方法
12.封装与隐藏
封装性
1.将属性XX私有化,同时,提供公共的方法去获取(getXX)和设置(setXX)
2.不对外暴露私有的方法
3.单例模式(将构造器私有化)
4.如果不希望类在包外调用,可以将类设置为确省
- 修饰类只能用确省或public
体现类及类的内部结构在被调用时的可见性的大小
this关键字
this理解为:当前对象 或 当前正在创建的对象
①在构造方法中使用
②在实例方法中使用:实例成员变量(this.成员变量),static成员变量(类名.成员变量)
this构造器
可以显式的用this(参数列表),调用本类的其他构造器
规定:this(参数列表)必须声明在当前构造器首行,每个构造器内部最多只能一个this构造器
super
成员变量与从父类继承的成员变量同名,子类就会隐藏所继承的成员变量,子类继承的方法只能操作子类继承和隐藏的成员变量。子类新定义的方法可以操作子类继承和子类新声明的成员变量,但无法操作子类隐藏的成员变量(使用super即可)
可以用来调用:属性,方法,构造器
在子类的方法或构造器中。通常使用super.属性/方法。显示调用父类中的声明或方法。一般省略super,当子父类同名时,super不能省略
13.继承extends
子父同包,子不能继承父的private ;子父不同包,子只能继承父的protected,public
- 一个类可以被多个子类继承
- 一个类只能有一个父类(单继承)
- c++支持多继承,java中支持单继承和多层继承
- 直接继承的父类叫直接父类
- 子类继承了直接父类之后,就继承了所有间接父类的方法和属性
- 所有的Java类都直接或间接的继承object类
14.重写overwrite
子类继承父类以后,可以对父类同名同参方法进行覆盖
子类重写的方法名和形参列表与父类被重写的形同
子类重写的修饰符不小于父类被重写的修饰符权限
子类不能重写父类中声明的private方法
在编译的时候,只能调用父类中声明的方法。在运行期,我们实际执行的是子类重写父类的方法编译看左边 运行看右边
对象的多态:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
对象的多态性只适用于方法,属性的编译和运行都看左边
向下转型
向下转型:使用强制类型转换符(将父类转化为子类)
使用强转时,可能出现ClassCastException异常,为了避免先进行instanceof判断
instanceof
a instanceof A:判断对象a是否为类A的实例,如果是,返回true
向上转型:多态
例如:
老虎是动物,动物是老虎的上转型对象
上转型对象仅仅不能操作对象新增的方法,变量
多态:父类的某个方法被其子类重写时,各自产生自己的功能行为
java中的2种多态:重写,重载16.接口interface
interface B
class A implement B实现接口implements,java可多实现接口,单继承
接口是一个抽象类,接口中的所有方法都是抽象方法
接口可以被extends
如果一个类声明实现一个接口,但没有重写接口中的所有方法,那这个类必须是抽象类
java中,接口和类是并列的两个结构
接口回调:当接口变量调用被类实现的接口方法时,就是通知相应对象调用这个方法;当接口变量存放了实现接口的类的对象的引用后,接口变量就可以调用类实现的接口方法
抽象和接口有哪些异同
- 都不能实例化,都有abstract方法
- 抽象类有构造器,接口不能声明构造器,单继承,多实现
demo1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30package Example;
public interface ShapeArea {
public abstract double doublegetArea();
public abstract double doublegetPerimeter();
}
package Example;
public class Rectangle implements ShapeArea {
double width;
double height;
public Rectangle(double w,double h){
this.width = w;
this.height = h;
}
public double doublegetArea() {
return width*height;
}
public double doublegetPerimeter() {
return (width+height)*2;
}
public String toString(){
System.out.println("width="+ width + ",height = " + height + ",periment = "+ doublegetPerimeter() + ",area="+ doublegetArea());
return null;
}
}
17.多线程
创建多线程的方式一:继承Thread类
创建一个继承于Thread的子类
重写run()方法
创建一个子类的对象
对象.start()
①启动多线程 ②实现run方法
Thread.currentThread().getName()输出当前线程的名字
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31package Example;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
/*
实现一个计数器,计数到100,在每个数字之间暂停1秒,每隔10个数字输出一个字符串 。
*/
public class Number extends Thread {
Lock lock = new ReentrantLock();
public void run(){
lock.lock();
for(int i = 0;i < 100; i++){
System.out.println(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(i%10 == 0){
System.out.println("----"+i);
}
}
lock.unlock();
}
}
/*继承Thread类
Number num = new Number();
num.start();
*/
方式二:实现Runnable()接口
创建一个实现Runnable接口的类
重写run()
创建实现类的对象
将此对象作为参数传递到Thread类,创建Thread对象
Thread对象.start()
方式一,二比较
优先使用Runnable接口的方法
①实现的方式没有类的单继承性的局限性
②实现的方式更适合来处理多个线程有共享数据的情况
1 | package Example; |
方式三:Callable
方式四:线程池
好处:
- 提高响应速度
- 降低资源消耗
- 便于线程管理
1 | //1.提供指定线程数量的线程池 |
corePoolSize:核心池大小
maximunPoolSize:最大线程数
keepAliveTime:线程没有任务时最多保持多长时间后会终止
线程常用方法
start()启动当前线程,调用当前线程的run()方法
run()将线程要执行的操作写在此方法中
currrentThread()静态方法,返回执行当前代码的线程
getName()获取当前线程的名字
setName()设置当前线程的名字
yield()释放当前cpu的执行权
join()在线程a中调用线程b的join(),此时线程a就进入阻塞状态,直到线程b完全执行完以后,线程a结束阻塞状态。
sleep(long millis)休眠
isAlive()判断线程是否存活
优先级
MAX_PRIORITY:10
MIN_PRIORITY:1
getPriority()
setPriority(int p)
运行不是绝对按照优先级,只是从概率上。
线程状态
新建–>就绪—><—运行—>死亡
新建到就绪调用start()
就绪到运行获取CPU执行权
运行到就绪失去cpu执行权或yield()
运行到死亡:
- 执行完run()
- 调用线程的stop()
- 出现error/exception且没有处理
运行到阻塞:
- sleep()
- join() //a join() b ;a线程阻塞
- 等待同步锁
- wait()
- suspend()
阻塞到就绪:
- sleep()时间到
- join()结束
- 获取同步锁
- notify()/notifyAll()
- resume()
解决线程安全 问题
方式一:同步代码块
synchronized(同步监视器){
//需要被同步的代码
}
①操作共享数据的代码,即为需要被同步的代码
②同步监视器:锁。任何一个类的对象都可以作为锁。多个线程必须要共用同一把锁
方式二:同步方法
方式三:lock
- 实例化
private ReentrantLock lock = new ReentrantLock();
- lock.lock(); lock.unlock();
synchronized与lock区别:lock手动结束
线程通信
- notify();//唤醒一个线程
- notifyAll();//唤醒所有线程
- wait();//一旦执行此方法,此线程就会进入阻塞,并释放同步监视器
只能出现在同步代码块或者同步方法
并且调用者要是监视器
sleep()与wait()的异同
一旦执行都会进入阻塞
Thread类中声明sleep();Object类中声明wait()
sleep()会自动释放监视器;wait()不能
18.异常
Error:Java虚拟机无法解决的问题如JVM系统错误。不编写针对性的代码进行处理
Expection:空指针。可以解决①终止程序②编写时提前处理
①try-catch-finally处理异常
②throws抛出异常
③throw(手动)声明异常
④用户自定义
异常对象的产生:
- 系统自动生成的异常对象
- 手动生成一个异常对象并抛出(throws)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33package Example.Excep;
//自定义异常
public class NoThisException extends Exception {
public NoThisException(){
super();
}
public NoThisException(String message){
super(message);
}
}
//抛出异常
public class Player {
public void play(int index) throws NoThisException {
if (index > 10) {
throw new NoThisException("您播放的歌曲不存在");
}
System.out.println("正在播放歌曲");
}
}
//处理异常
public class NumExceTest {
public static void main(String[] args) {
Player player = new Player();
try{
player.play(9);
}catch(NoThisException e) {
System.out.println(e.getMessage());
}
}
}19.集合
数组弊端: - 一旦初始化,长度就确定了
- 方法有限效率低
- 对于无序,不可重复的需求无法满足
- 元素类型单一
collection(单列集合)list(有序可重复–动态数组)
Vector
ArrayList
LinkedList
set(无序,不可重复)
HashSet
LinkedHashSet
SortedSet
TreeSet1
2
3
4
5
6
7
8/*ArrayList arr = new ArrayList();
for (int i = 0; i < 10; i++) {
arr.add((int)(Math.random()*10));
}
Iterator iterator = arr.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}*/
20.常用类
String
不可变字符序列
实现了Serializable接口:表示字符串是支持序列化的
实现Comparable接口:表示字符串比较大小
实例化方法
字面量定义(常量池)
new + 构造器(堆)
String s = new String(“abc”);
在内存中实际创建了2个对象,一个是堆空间中的new结构,另一个是char[]对应的常量池中的数据
值传递:基本数据类型传的是值,引用数据类型传的是地址
底层都用char[] 存储
String:不可变
StringBuffer:可变,线程安全,效率低
StringBuilder:可变,没有scynoriza,线程不安全,效率高
效率:StringBuilder > StringBuffer > String
Date
JDK8之前
System类中的currentTimeMiles()
java.util.Date类
- java.sql.Date类
SimpleDateFormat
对日期Date类的格式化和解析
两个操作:①格式化:日期–》字符串
②格式化逆过程(注意参数符合格式)
Calendar(抽象类,不能实例化,可变性)
实例化可以调用其静态方法getInstance()
getTime(): 日历类–》Date
setTime(): Date—>日历类
获取这个月第几天的时候,1号是0
JDK8之后
LocalDateTime相较于LocalDate,LocalTime,使用频率更高
- now();
- of():设置指定的年,月,日,时,分,秒没有偏移量
- 不可变性
instant:瞬时时间戳//子午线的时间
java.time.format.DateTimeFormatter:格式化
java比较器
- Comparable接口
- 自然排序
- Comparator接口
- 定制排序
System类
void gc():垃圾回收
Math类
关于数学的计算都可以用
BigInteger类
对于超过long范围的int数表示
任意位数的数
BigDecimal类
任意精度的数
关于JDK8前后的日期时间相关类总结
- java.until.Date和java.sql.Date—-> Instant
- SimpleDateFormat —-> DateTimeFormatter
- Calendar —-> LocalDate,LocalTime,LocalDateTime
21.枚举类
当类的对象只有有限个,确定的
需要定义一组常量时,强烈建议使用枚举类
如果枚举类中只有一个对象,可以作为单例模式的实现方式
定义
自定义枚举类(JDK5.0前)
1
2
3
4
5
6
7
8
9
10
11class s{
//1.声明S对象的属性:private final修饰
private final String name;
//2.私有化构造器,并给对象属性赋值
private s(){
this.name = name;
}
//3.提供当前枚举类的多个对象:public statuc final
public static final SPRING = new s("春");
public static final SUMMER = new s("夏");
}enum关键字(JDK5.0之后)
定义的枚举类默认继承于java.lang.Enum
1 | enum s{ |
常用方法
- values():返回枚举类型的对象数组。遍历
- valueOf(String str):将字符串转为对应的枚举类对象
- toString()
22.注解
jdk5.0之后新增功能
Annotation其实就是代码中的特殊标记,这些标记可以在编译,类加载,运行时被读取
- 文档注解
- jdk内置3个基本注解
- @Override
- @Deprecated:表示所修饰的元素已经过时
- @SuppressWarnings:抑制编译器警告
- 跟踪代码依赖性
自定义
参照@SuppressWarning的定义
元注解
修饰其他Annotation,前2个元注解常用。
- Retention:生命周期SOURCE\CALSS默认\RUNTIME
- 只有声明为RUNTIME生命周期的注解,才能通过反射获取
- Target:用于指定 注解可以修饰那些元素
- Document:表示修饰的注解会被javadoc提取到文档
- Inherited:使其具有继承性
jdk8新特性
可重复@Repeatable
23.泛型
jdk5.0新增的特性