JavaSE
1. Java 基础
1. JDK、JRE
JRE | JDK | |
---|---|---|
含义 | java 运行环境(java) | java 开发工具(javac) |
内容 | java 核心类库 + JVM | JRE + 开发工具 |
位置 | 客户端装的 | 开发者(程序员)装的 |
java -version
:可以查看 JDK 的版本
配置环境变量
path
:文件路径
classpath
:类文件路径,规定 java JVM
在哪里去查找 class 文件
,如果没有配置就在当前目录下
查找,配置后就在配置后的目录下
查找
配置临时环境变量:
set path # 查看环境变量
set path=值 # 设置环境变量
set path=空格 # 删除环境变量
set path=新值;%path% # 在已有的环境变量,再加新值
set classpath=路径 # 在指定路径下查找
set classpath=路径; # 先在配置目录(指定路径)下查找,如果没有查找到,就在当前目录下查找
set classpath=.;路径 # 在当前路径和指定路径下查找
2. 标识符
概念:java 所有的名字(变量名,数组名,方法名,类名,接口名…)
名字定义规则:
- 组成 = 字母 + 数字 + 下划线(_) + 美元符号($)
- 不能以数字开头
- 严重区分大小写
- 不能是关键字:java 中具有特殊含义的单词(48 个)
- 不能是保留字:
goto
、const
3. 数据类型
3.1 基本数据类型(八大基本数据类型)
-
整型:所有没有小数点的数
数据类型 关键字 所占字节数 取值范围 字节型 byte 1 -128(2 的 7 次方)到 127(减-1) 短整型 short 2 -2 的 15 次到 2 的 15 次方减 1 整型 int 4 -2 的 31 次到 2 的 31 次方减 1 长整形 long 8 -2 的 63 次到 2 的 63 次方减 1 注意:
long 值
超过了int 范围
(2147483647)必须加 l 或者 L -
浮点型:所有有小数点的数
数据类型 关键字 所占字节数 注意 单精度 float 4 值后面必须加 f 或者 F 双精度 double 8 值后面加 d 或者 D -
字符型:所有的字符,只可以存储单个字符
数据类型 关键字 所占字节数 注意 字符型 char 2 值必须放在单引号(’’)里面 -
布尔型:所有产生两个相反的结果的数据
数据类型 关键字 所占字节数 注意 布尔类型 boolean 1 值只有两个 true 和 false
3.2 引用数据类型
- 数组
- 类(String 字符串类)
- 接口
3.3 数据类型的转换
精度排序(低到高):byte short char int long float double
自动转换(低转高):低精度类型 变量名 1=值; 高精度类型 变量 2=变量 1;
强制转换(高转低):高精度类型 变量名 1=值;低精度类型 变量 2=(低精度类型)
变量名 1;
byte+byte=int
short+short=int
4. 运算符
运算符 | |
---|---|
算术运算符 | + - * / %(求余) ++ – |
赋值运算符 | += -= *= /= %= |
比较运算符 | > >= < <= == != |
逻辑运算符 | & (与) 、| (或)、 ! (非)、 ^ (异或)、 && (双与,效率更高) 、||(双或) |
条件运算符(三目(三元)运算符) | boolean 条件 ? 条件为 true 时执行的语句 : 条件为 false 时执行的语句 |
位运算符 | <<(左移)、>>(右移)、>>>(无符号右移)、&(与) 、|(或) 、^(异或)、~(反码) |
位运算符
<<:左移几位其实就是该数据乘以 2 的几次方。可以完成 2 的次幂运算
如:3<<2=12 ==>3*2*2=12
>>:右移几位其实就是该数据除以 2 的几次方。对于高位出现的空位,原来高位是什么就用什么补这个空位
如:3>>1=1 ==>3/2=1
>>>:无符号右移,数据进行右移时,高位出现的空位,无论原高位是什么,空位都用 0 补
如:3>>>1=1 ==>3/2=1
^:一个数异或同一个数两次,结果还是这个数。如 6^3^3=6
5. java 语句
-
顺序结构:默认的执行流程
-
选择结构(分支结构)
-
if
-
单分支
if( boolean 条件 ){ } // boolean 条件为 true 是执行的语句
-
双分支
if( boolean 条件 ){ // boolean 条件为 true 是执行的语句 }else{ } // boolean 条件为 false 是执行的语句
-
多分支
if( boolean 条件 1 ){ // boolean 条件 1 为 true 是执行的语句 }else if( boolean 条件 2 ){ // boolean 条件 2 为 true 是执行的语句 }else if....{ // boolean 条件 n 为 true 是执行的语句 }else{ } // 以上条件均不满足时执行的语句
-
-
switch
// 注意:switch 表达式应为:byte、short、int、char、String switch(表达式){ case 常量 1: //如果表达式==常量 1 就执行的语句 [break;] case 常量 2: //如果表达式==常量 2 就执行的语句 [break;] case 常量 n: //如果表达式==常量 n 就执行的语句 [break;] default: //如果表达式和所有 case 都不相等执行的语句 }
-
-
循环结构
-
while
while(boolean 条件){ //循环执行的代码 }
-
do while
do{ //循环体 }while(boolean 条件);
do-while 和 while 的区别?
-
for
for(初始化表达式;boolean 条件;迭代){ //boolean 条件为 true 时循环执行的代码 }
-
-
局部代码块:可以定义局部变量的生命周期
{ // 局部代码块 // 代码 }
关键字 break 和 continue
break:跳出
语句(循环、switch)执行,应用于选择和循环结构
continue:结束本次
循环,继续
下一次循环,应用于循环结构
注意
:
-
这两个语句离开应用范围,存在是没有意义的
-
这两个语句
单独存在
,后面都不可以有语句,因为执行不到
6. 函数
-
函数结构:
// 修饰符 返回值类型 函数名(参数类型 参数名 1,参数类型 参数名 2,....) public static void main(String[] args) { // 执行语句(方法体) return 返回值; }
-
函数的重载(overload)
重载:在同类中,函数名相同,参数列表不同(顺序、个数,类型不同)即可,与返回值类型无关
7. 数组
数组的特点
- 是一种数据类型,是一种引用数据类型
- 数据类型申明的变量存储的是一个数组对象
- 数组对象是一个可以存储多数据的容器
- 数组对象可以是任何类型,但每个数据类型必须保持一致
- 每个数据称为一个元素
- 数组一旦创建,其长度不可变
数组的声明
-
先定义,后赋值
数据类型[] 数组名 = new 数据类型[长度]; // 定义数组 数组名[下标] = 值; // 给对应下标元素赋值
-
定义并赋值
数据类型 [] 数组名 = new 数据类型[长度]; 数据类型 [] 数组名 = new 数据类型[]{ 元素 1,元素 2,...,元素 n}; 数据类型 [] 数组名 = { 元素 1,元素 2,...,元素 n}; //不规范,但常用
-
获得数组的长度
数组名.length
-
遍历(for/foreach)
-
元素有默认值
整型:0 float:0.0f double:0.0 char:空白字符
内存剖析
栈内存:存储的是局部变量
(既是方法中或局部代码块中的变量),而且变量所属的作用域一旦结束,该变量就自动释放
堆内存:存储的是数组和对象
(其实数组就是对象),凡是 new 建立的储存在堆
中
数组的最值、遍历、排序、查找
-
最值
-
方法1:定义变量记录较大的
值
public static int getMax(int[] arr){ int maxElement = arr[0]; // 初始化为数组中的任意一个元素。 for(int x=1; x<arr.length; x++) { if(arr[x]>maxElement) maxElement = arr[x]; } return maxElement; }
-
方法2:定义变量记录较大的
下标
public static int getMax(int[] arr){ int maxIndex = 0; //初始化为数组中任意一个角标。 for(int x=1; x<arr.length; x++){ if(arr[x]>arr[maxIndex]) maxIndex = x; } return arr[maxIndex]; }
-
-
遍历
public static void printArray(int[] arr){ System.out.print("["); for(int x=0; x<arr.length; x++){ if(x!=arr.length-1) System.out.print(arr[x]+", "); else System.out.println(arr[x]+"]"); } }
-
排序:其实
真正开发的时候
,一般用 Aarrys.sort(数组工具类
的排序方法)-
顺序排序
-
方法1
int a[]={ 5,2,3,1,4}; for(int i=0;i<a.length-1;i++){ // 控制比较的轮数 for(int j=i+1;j<a.length;j++){ // 控制本轮的比较次数 if(a[i]>a[j]){ // 如果前一个数大于后一个数 int temp=a[i]; // 将后一个数与前一个数交换位置 a[i]=a[j]; a[j]=temp; } } }
-
方法2:
减少换位的操作,此方法效率更高
public static void selectSort_2(int[] arr){ for(int x=0; x<arr.length-1; x++){ int num = arr[x]; int index = x; for(int y=x+1; y<arr.length; y++){ if(num>arr[y]){ num = arr[y]; index = y; } } if(index != x){ // 如果不等交换位置 int temp = arr[x]; arr[x] = arr[index]; arr[index] = temp; } } }
-
-
冒泡排序
int a[]={ 5,2,3,1,4}; for(int i=0;i<a.length-1;i++){ // 控制比较的轮数 for(int j=0;j<a.length-i-1;j++){ // 控制本轮的比较次数 if(a[j]>a[j+1]){ // 如果前一个数大于后一个数 int temp=a[j]; // 将后一个数与前一个数交换位置 a[j]=a[j+1]; a[j+1]=temp; } } }
-
-
查找
-
无序数组的查找
public static int getIndex(int[] arr,int key){ for(int x=0; x<arr.length; x++){ if(arr[x]==key) // 查到就返回 值 return x; } return -1; // 没查到返回 -1 }
-
有序数组的查找:折半/二分查找
真实开发
时,使用 Arrays.binarySearch 方法(数组工具类
的二分查找
)public static void main(String[] args) { int[] arr = { 13,15,19,28,33,45,78,106}; // 有序数组 int index = halfSearch(arr,15); // 折半查找 int index1 = Arrays.binarySearch(arr,15);// 二分查找 System.out.println("index="+index+"index1="+index1); //存在返回的具体的角标位置,不存在返回-1 }
-
折半查找
-
方法1
public static int halfSearch(int[] arr,int key){ int min = 0; int max = arr.length-1; int mid = (max+min)/2; while(arr[mid]!=key){ if(key>arr[mid]) min = mid + 1; else if(key<arr[mid]) max = mid - 1; if(max<min) return -1; // 不存在返回-1 mid = (max+min)/2; // 重新赋中间值 } return mid; // 存在返回的具体的角标位置 }
-
方法2
public static int halfSearch_2(int[] arr,int key){ int mid; int min = 0; int max = arr.length-1; while(min<=max){ mid = (max+min)>>1; // 相当于 mid = (max+min)/2 if(key>arr[mid]) min = mid + 1; else if(key<arr[mid]) max = mid - 1; else return mid; } return -min-1; }
-
二分查找 :使用 Arrays.binarySearch 方法
-
-
多维数组
多维数组:如果一个数组的元素是数组,该数组是多维数组
二维数组:如果如果一个数组的元素是一维数组,该数组是二维数组
-
定义二维数组与赋值
数据类型 [][] 数组名 = new 数据类型[长度][长度]; // 定义 数组名[下标][下标]=值; // 赋值 数据类型 [][] 数组名 = { { 数据 1,数据 2,数据 n},{ 数据 1,数据 2,数据 n}}; // 定义时就赋值
-
遍历(与一维数组遍历方法类似)
2. 面向对象(OOP)
1. 面向对象概述
类:由一群相同共性的对象组成的群体
对象:一切客观存在,可以相互区别的个体
对象和类之间的关联:对象是类的具体化,类是对象的抽象化(模板)
匿名对象:没有名字的对象 。其实就是对象的简写格式
- 当对象的
方法仅调用一次
的时候,就可以简化成匿名对象
- 匿名对象可以作为
实际参数
进行传递
1.1 类
类的格式:
修饰符 class 类名{
// 1.属性(成员变量、全局变量):描述类的信息
[修饰符] 数据类型 变量名[=初始值];
// 2.构造器 构造函数 构造方法 constructor 作用是:创建对象
[修饰符] 类名([参数列表]){
//方法名必须和类名一致
//初始化代码
}
// 3.方法 行为 函数:让对象具有某种特定的功能
[修饰符] 返回值(void)方法名([参数列表]){
//行为代码
}
}
-
全局(成员)变量
和局部变量
的区别区别 成员变量 局部变量 存在位置 成员变量定义在类中 局部变量定义在方法中 默认值 成员变量有默认值 局部变量若使用必须赋初始值 修饰符 成员变量可以用 所有修饰符
修饰局部只能用 final 修饰符修饰 作用范围 成员变量能作用于整个类 局部变量只能作用于方法,语句,局部代码块中 存储位置 成员变量储存在堆内存的对象中 局部变量储存于栈内存的方法中 生命周期 随着 对象的创建
而存在,消失而消失随着 所属区域的执行
而存在,结束而释放 -
成员变量
和静态变量(类变量)
的区别区别 成员变量 静态变量 生命周期 随着对象的创建而存在,消失而消失 随着类的加载而存在,随着类的消失而消失 调用方式 成员变量只能被对象调用 静态变量可以被对象调用,还可被类名调用 存储位置 成员变量数据存储在堆内存的对象中,所以也叫对象的特有数据 静态变量数据存储在方法区(共享数据区)的静态区,所以也叫对象的共享数据 别名 成员变量也称为 实例变量
静态变量称为 类变量
-
普通方法
和构造器方法
的区别区别 构造方法 普通方法 格式 构造方法没有返回值 普通方法必须有返回值 作用 构造方法的作用是创建对象 普通方法的作用是让对象具有某种特定的功能 调用时机 创建对象时调用构造方法 普通方法必须在创建对象之后,用对象名来多次调用 默认值 一个类中没有构造器,系统会默认提供一个
无参构造器,当类中有构造器时,系统将不再提供 -
参数
- 概念:参数本质就是一个
特殊的局部变量
- 作用:调用方法时
动态的传入数据
- 传参:调用方法时,实参传递给形参
- 概念:参数本质就是一个
-
值传递和引用传递
- 值传递:对象被值传递了,意味着传递了对象的一个副本,该副本被改变不会影响源对象的值
- 引用传递:对象被引用传递了,意味着传递的引用(堆的地址),外部对象被改变,会影响源对象的值
-
返回值
-
无返回值:void
-
有返回值
[修饰符] 返回数据类型 方法名([参数列表]){ // 行为代码 return 值; // 结束方法并返回一条数据 }
-
1.2 几个关键字和修饰符
-
overload(重载):在同类中,方法名相同,参数列表不同(顺序、个数,类型不同)即可
-
override(重写 ):在子类中,方法名相同,返回值相同,参数列表相同(个数、类型、顺序)
当父类的方法不能满足子类的需求,
子类
对该方法重新定义,称为重写
注意:- 子类的访问修饰符必须 >= 父类
- 静态只能覆盖静态,或被静态覆盖(此处有错误:静态方法不能被重写,可以被继承)
overload
和override
的区别
-
this(当前对象)
- 调用成员变量:当成员变量名和局部变量名相同时,局部变量把成员变量隐藏起来,如果想调用成员变量,必须加
this. 成员变量名
- 调用构造器:如果当前的构造器无法完成初始化,需借助其他构造器帮助完成初始化,使用
this(参数)
,该句必须放在第一行
,该调用不会创建对象,只是借助方法来完成初始化
- 调用成员变量:当成员变量名和局部变量名相同时,局部变量把成员变量隐藏起来,如果想调用成员变量,必须加
-
super:就是 this 的父类对象
-
调属性:子类属性和父类属性相同时,想使用父类属性,使用
super.属性名
-
调方法:子类重写父类的方法,当子类中想调用该父类的方法,使用
super.方法()
-
调构造器:
super([参数])
,如果子类构造器没有调用父类构造器,默认调用父类无参构造器,调用构造器必须放在方法的第一行,this([参数])和 super([参数])不能共存注意:
- 每一个
子类的构造方法
在没有显示调用 super()系统都会提供一个默认的 super()
,super() 书写在第一行 - 可以在
子类构造方法中
显示调用 super([参数列表]),完成对特定父类构造方法的调用 - 当成员变量和局部变量重名的时候用 this 区分。
当父类和子类的成员变量重名
时用 super 区分。 - this 指代一个本类对象的引用。
super 代表一个父类空间。super 指向父类。
- 每一个
优先级:static > 父类 > 属性 > 构造器
-
-
static 修饰符:优先被加载,且执行一次
-
修饰变量:称为
类变量
,因为该变量是所有对象共享的变量调用:可以用
对象名
来调用,也可以用类名
调用注意:
静态变量
和实例变量(对象变量)
的区别? -
修饰方法:称为类方法,静态方法只能调用静态变量和静态方法
调用:可以用
对象名
来调用,也可以用类名
调用注意:
- .static 优先于对象存在,因为 static 的成员随着类的加载就已经存在了
静态方法只能访问静态成员
。(非静态既可以访问静态,又可以访问非静态)- 类方法不能使用 this 或 super,因为没有 this 实例可供使用
- static 修饰的
方法
不能被重写,可以被继承
,static和 abstract 不能共存
静态方法
和实例方法(对象方法)
的区别及静态变量
和实例变量(成员变量)
的区别
-
静态代码块:
static{ //代码语句:此代码仅执行一次 }
-
-
final 修饰符
-
final 修饰
变量
:变量就变成常量,只能赋值一次,一旦被赋值不能再次赋值
final 修饰的变量是一个常量,对所有的对象都一样,一般在 final 之前加上 static
常量所有字母都大写,多个单词中间用_连接
-
修饰
成员变量
:成员属性定义成常量必须赋初始
值,或在构造器中赋值
-
修饰
局部变量
:可以不赋初始值,但在方法结束之前
赋值(冗余代码)
-