文章目录
常识
平台版本
- javaSE: 标准版
- javaEE: 企业版
- javaME: 微型版
开发工具
- JDK: java开发工具包, 包含了jre+开发工具
- JRE: java运行时环境, 包含了JVM和运行java程序所必须的环境
- JVM: 虚拟机, 负责加载.class并运行.class文件
运行流程
基础语法
标识符
用来定义类,对象, 变量的名字
- 只能以字母, 数字, 下划线(_), 美元符($)组成
- 不能以数字开头
- 严格区分大小写
- 不能使用关键字
- 推荐使用驼峰命名法
- 小驼峰命名: 单词的首字母小写, 后面首字母大写
- 大驼峰命名: 所有单词的首字母大写
注释
用来标注代码的说明, 不会被程序编译
- 单行注释
//
- 多行注释
/*/
- 文档注释
/** */
关键字
一共有50个关键字+3个保留字, 不能用作标识符
变量
- 用来保存可变的值
- 语法:
变量类型 变量名字 = 变量值
成员变量
- 类里方法外, 不用初始化, 会被自动初始化为默认值
- 作用在整个类中, 随着类的消失而消失
定义方法:
- 先声明再赋值
int a;
a= 18;
- 声明同时赋值
ina a = 18;
案例:
/** 打印出个人信息*/
//打印一句话
System.out.println("欢迎来到Java世界");
// 需求: 打印XXX今天x岁了,月薪xxx,感慨Java是世界上最好的语言
System.out.println("XXX今天x岁了,月薪xxx,感慨Java是世界上最好的语言");
int age = 18; //定义年龄变量
double salary = 10000.99; //定义工资变量
String name = "李逵"; // 定义名字变量
System.out.println(name + "今年" + age + "岁了," + "月薪" + salary + ",感慨Java是世界上最好的语言"); //字符串的拼接使用+号
局部变量
- 方法里或者局部代码块中, 必须要声明的同时赋值
- 作用在本方法中
数据类型
基本类型
案例:
/** 打印基本类型的取值范围*/
byte byteMin = Byte.MIN_VALUE; //自带的工具包
byte byteMax = Byte.MAX_VALUE;
System.out.println("byte最大值" + byteMax );
System.out.println("byte最小值" + byteMin );
short shortMin = Short.MIN_VALUE;
short shortMax = Short.MAX_VALUE;
System.out.println(shortMin);
System.out.println(shortMax);
int intMin = Integer.MIN_VALUE;
System.out.println(intMin);
Boolean b1 = true; //1 真
Boolean b2 = false; //0 假
System.out.println(b1);
//char类型的数据需要使用单引号包裹
char c1 = 'a';
char c2 = '中';
char c3 = 97;
char c4 = '9';
System.out.println(c1);
System.out.println(c2);
System.out.println(c3);
System.out.println(c4);
引用类型
- 除基本类型外都是引用类型
字面值规则
- 整数 : int类型
- 浮点数: double类型
- byte, short, char三种比int小的类型,使用范围内的值直接赋值
- 三个字面值后缀 L-long F-float D-double
- 进制前缀 0b-二进制 0-八进制 0x-十六进制
运算规则
- 运算结果的数据类型与最大类型保持一致
- int/int -> int
- int/double->double
- 整数运算可能会出现溢出的现象,一旦溢出,数据就不正确的了(光年案例)
- byte short char三种比int小的类型,运算时需要先自动提升成int类型再参与运算
- 浮点数的特殊值:Infinity NaN
- 浮点数运算不精确的现象,解决方案:BigDecimal
- 注意1:不能使用double类型参数的构造方法,需要使用String类型的构造函数,否则还会出现不精确的问题
- 注意2:除法运算时,如果出现除不尽的现象还会报错,所以需要指定保留位数与舍入方式(四舍五入)
类型转换
口诀: 小转大 直接转,大转小 强制转,浮变整 小数没
- 注意1:boolean类型不参与类型转换
- 注意2:基本类型能否转换,取决于类型的取值范围,而不是字节数,字节数只能做参考
- 注意3:我们这里说的是基本类型,引用类型直接的转换与强转取决于是否有继承关系:
- 你可以说小猫是一只小动物,但你不能说小汽车是一个水果,后面这种就会出现类型转换异常
- 你可以说小猫是一只小动物,但你不能说小汽车是一个水果,后面这种就会出现类型转换异常
运算符
流程控制
分支结构
- if单分支结构
if(判断条件){
符合判断条件后要执行的代码,如果不符合判断条件,就跳过此句,执行后面
}
- if-else 多分支结构
if(判断条件){
符合判断条件后要执行的代码,如果不符合判断条件,就跳过此句,执行else中的语句
}else{
不符合 if 的判断条件,执行的代码,属于其他情况
}
- if-else if-else 嵌套分支结构
if(判断条件1){
符合判断条件1后要执行的代码,如果不符合判断条件1,就跳过此句,执行判断条件2
}else if(判断条件2){
符合判断条件2后要执行的代码,如果不符合判断条件2,就跳过此句,执行判断条件3
}else if(判断条件3){
符合判断条件3后要执行的代码,如果不符合判断条件3,就跳过此句,执行保底选项
}else{
保底选项,以上条件均不满足的情况下,执行此处代码【可选项】
}
选择结构
switch(a){
case 1 : 操作1;break;【可选】
case 2 : 操作2;break;【可选】
case 3 : 操作3;break;【可选】
case 4 : 操作4;break;【可选】
default : 保底选项;【可选】
}
执行顺序:先拿着变量a的值,依次与每个case后的值做比较,如果相等,就执行当前case后的操作,若case后没有break,就绪继续执行下一个case后的操作,如果一直没有遇到break,就会发生穿透的现象,包括default
- 注意1:小括号中a支持的类型:byte short char int String Integer
- 注意2:如果配置了default默认选项,而且没有任何case被匹配到,就会执行default后的操作
- 注意3:case的个数、是否加break、是否加default全是可选的,取决于业务
循环结构
- 普通for循环
for(开始条件 ; 循环条件 ; 更改条件){
循环体
}
- 注意1:写法小窍门:从哪开始 到哪结束 循环变量如何变化
- 注意2:for循环能够执行多少次,取决于循环变量可以取到几个值
- 嵌套for循环
外层循环控制的是轮数,内层循环控制的是每一轮中执行的次数
对于图形而言,外层循环控制的是行数,内层循环控制的是列数
for(){ //外层循环
for(){//内层循环
我是一个循环体
}
}
- 高效for循环
for(遍历到的元素的类型 遍历到的元素的名字 :要遍历的数组/集合名){
循环体
}
- 优点:写法简单,效率高
- 缺点:只能从头到尾的遍历数据,不能进行步长的选择
- while循环
使用while通常用来写死循环,但是注意死循环必须要设置出口
while(判断条件){
循环体
}
- do-while循环
do-while循环一定会执行一次,然后再判断,如果符合条件,再执行后面的循环
do{
循环体
}while(判断条件);
循环之间的比较
- 如果明确知道循环的次数/需要设置循环变量的变化情况时–使用for循环
- 如果想写死循环–while(true){}
- 如果需要先执行一次,再做判断–do-while循环
- 循环之间是可以互相替换的,但是最好使用比较合适的循环结构
方法
定义普通方法
格式: 访问控制符 返回值类型 方法名(参数列表){ 方法体 }
调用方法
方法名(参数)
方法的执行顺序
方法的重载
在同一个类中出现方法名相同但参数列表不同的现象
注意:方法之间能否构成重载,取决于方法的参数个数与类型,与方法的参数名无关
重载的意义:为了方便外界对方法进行调用,什么样的参数程序都可以找到对应的方法来执行,体现出程序的灵活性
方法的传值:基本类型传递的是实际值,引用类型传递的是地址
而且方法的参数属于形参,只是格式上需要定义,但是调用方法时起不到限制的作用
- 形参:定义方法的时候的参数列表
- 实参:使用方法的时候传入的数据
方法的重写
使用@override注解
子类继承父类以后,如果子类对父类的功能不满意,可以重写父类的方法
-
重写的规则:两同两小一大
-
一大:子类方法的修饰符范围 >= 父类方法的修饰符范围–指的是访问控制符
-
两同:方法名相同,参数列表相同
-
两小:
- 子类方法的返回值类型 <= 父类方法的返回值类型【这个大小是继承关系,不是数值的大小】
- 子类方法抛出的异常类型 <= 父类方法抛出的异常类型
-
注意:如果父类方法的返回值类型是void,子类保持一致即可
-
注意:子类不可以重写父类的私有方法,还是因为不可见
-
重写的意义:是在不修改源码的前提下,进行功能的修改和拓展(OCP原则:面向修改关闭,面向拓展开放)
-
拓展:方法的递归 ,难度较大
权限修饰符
数组Arrays
标志: []
数组的创建
- 动态创建
- 指定数组的类型与长度
int[] a = new int[5];
- 指定数组的类型与长度
- 静态创建
- 指定数组的类型与每一个具体元素(暗含了数组的长度)
int[] a = {1,2,3,4,5};
int[] a = new int[]{1,2,3,4,5};
- 指定数组的类型与每一个具体元素(暗含了数组的长度)
数组的操作
通过数组的下标index来操作数组中的元素
数组下标从0开始,最大下标是数组的长度-1,a.length-1
比如:a[2]–表示的是数组的第3个元素,数组容易出现数组下标越界的问题,其实就是访问了不存在的位置
数组的创建过程
- 在内存中开辟一块连续的内存空间,长度为5
- 给数组完成初始化的过程,给每个位置上的元素赋予对应类型的默认值,此处是0
- 数组完成初始化后,会给数组分配一个唯一的地址值
- 把数组的地址值交给引用类型int[]的变量a来保存
- 后面可以根据下标给数组的每个元素赋值,比如1,2,3,4,5对应的下标是a[0]。。。a[4]
数组的遍历
使用for循环遍历数组,所以for循环的循环变量代表的是数组的下标,最小值是0,最大值是a.length-1
注意数组下标越界的问题
public class ReviewDemo {
public static void main(String[] args) {
int[] a = new int[10];
for(int i = 0;i<a.length;i++) {
//System.out.println(i);//打印的是数组的下标0-9
a[i] = i+11;//a[i]代表的是数组中每一个具体的元素
}
System.out.println(Arrays.toString(a));
//[11, 12, 13, 14, 15, 16, 17, 18, 19, 20]
}
}
数组工具类
- Arrays.toString(数组名) : 打印数组中所有的元素
char[]底层做了处理,所以可以直接打印数组的元素内容,但是其他任何类型的数组想要查看具体元素需要:使用数组的工具类Arrays.toString(数组名);
/**s是引用类型的变量,保存的数组的地址值
* 由于Java对char类型做了底层处理,所以char[]可以直接打印具体内容
* 但除了char类型以外,其他任何类型的数组想要查看具体元素需要使用数组的工具类arrays的tostring(数组名)来完成*/
String[] s = {"a", "b", "c"};
System.out.println(s);
System.out.println(Arrays.toString(s));
- Arrays.sort(数组名) :对数组中的元素进行排序
- Arrays.copyOf(原来数组的名字,新数组的长度)
// copyOf复制数组
private static void ArrayCopyOf() {
// 创建数组
int[] from = {1, 2, 3, 4, 5};
// 数组的复制
int[] to = Arrays.copyOf(from, 5);
System.out.println(Arrays.toString(to));
// 数组的缩容
/**先创建指定数组的新数组,然后按照这个长度从原数组from中复制对应的个数元素,类似于截取的效果
* Arrays.copyOf(要复制的数组名,复制后的数组长度)*/
int[] to2 = Arrays.copyOf(from, 3);
System.out.println(Arrays.toString(to2));
// 素组的扩容
/**先创建指定数组的新数组,然后按照这个长度从原数组from中复制对应的个数元素,没有被复制的元素是数组类型的默认值*/
int[] to3 = Arrays.copyOf(from, 10);
System.out.println(Arrays.toString(to3));
// 指定收尾截取数组
/**截取的范围是按照数组下标操作的,含头不含尾
* Arrays.copyOfRange(要复制的数组名,开始下标,结束下标)*/
int[] to4 = Arrays.copyOfRange(from, 2, 4);
System.out.println(Arrays.toString(to4));
}
冒泡排序
先将数组里下标为0和1的两个数据进行比较, 大的数值移到后面, 再比较下标为1和2的数值, 依次到最后
这样就会获得从小到大的数组排序
写法: 使用嵌套for循环, 外层循环控制的是比较的轮数,内层循环控制的是比较的次数
// 用于实现冒泡排序
private static void method(int[] a) {
/**使用嵌套for循环完成冒泡排序*/
// 1. 外层循环:控制的是比较的轮数,假如有n个数,最多控制n-1轮
// 从哪开始1 到哪结束A.length-1 变化i++
for (int i = 1; i <= a.length-1; i++) {
for (int j = 0; j < a.length - i; j++) {
// System.out.println(j);
// 比较两个相邻元素的大小
if (a[j] > a[j + 1]) {
int t;
t = a[j];
a[j] = a[j + 1];
a[j + 1] = t;
}
}
System.out.println("第" + i + "轮:" + Arrays.toString(a));
}
System.out.println("排序后:" + Arrays.toString(a));
// 2. 内层循环:控制的是每一轮比较的次数
}