JAVASE
注释
注释三种:单行注释 多行注释 文档注释
//单行注释 /* 多行注释 */ /** *文档注释 *与JavaDoc联合使用 */
标识符
标识符:类名,变量名已经方法名都被称为标识符,都应该以字母,美元符($),或者下划线(_)k开头,首字母后可以是字母,美元符($),或者下划线,数字
不能使用关键字作为标识符
大小写敏感
数据类型
java是强类型语言:要求变量的使用要严格符号规定,所有变量必须先定义后才能使用
分为:
基本类型:
数值类型:
整数类型:
byte:一个字节,-128到127
short:两个字节,-32768到32767
int:四个字节,
long:八个字节
浮点类型:
float:四个字节
double:八个字节
字符类型:
char:两个字节
boolean类型:
占一位,只有true和false两个
引用类型:类,接口,数组
位(bite):计算机内部数据存储的最小单位
字节(byte):计算机中处理数据的基本单位,习惯用B表示
1B=8bite
1024b=1kb
1024kb=1M
1024M=1G
数据类型扩展
进制:
二进制:0b 十进制 八进制0 十六进制0x
浮点数扩展:
在银行业务中无法使用float和double,会出现下面问题:
float f = 0.1f; double d=1.0/10;
而在判断f==d时结果为false
因为float是有限,离散,舍入误差,大约,接近但不等于
所以最好完全避免使用浮点数进行比较
银行业务使用数学工具类BigDecimal
强制转换
(强转后的类型)变量名
所有的字符本质还是数字
编码 Unicode 里面字符对应
转义字符:\t 制表符 \n 换行
类型装换
低-----------》高
byte,short,char--->int--->float--->double
不能对布尔值装换
不能把对象类型转换为不相干的类
装换可能会内存溢出,或者精度问题
强制装换 高--》低
自动装换 低---》高
操作比较大的数是注意溢出问题
JDK7新特性,数字之间可以用下划线分割
int big=10_0000_0000
数字比较大计算应该先转型在计算,计算后在转型有问题
变量
变量名,变量类型,作用域
实例变量:从属于对象;如果不自行初始化,会赋该类型的默认值,布尔类型默认值为false,除了基本类型,其余默认值都是false
局部变量:必须声明和初始化值
类变量:从属于类
常量
常量:不能改变的变量
格式:
final int A = 1;
通过final来定义,一般用大写
变量的命名规范
类成员变量:首字母小写和驼峰原则
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线
类名:首字母大写和驼峰原则
方法名:首字母小写和驼峰原则
运算符
long a = 123121123L; int b = 122; short c = 10; byte d = 5; sout(a+b+c+d); sout(b+c+d); sout(c+d);
上面加输出的结果第一个为long类型,其他为int
因为如果a+b+c+d中有long类型,加的结果就是long类型
有double类型,加的结果就是double类型
其他结果都是int类型
很多运算我们会使用工具类
幂运算:
3的二次方
double pow = Math.pow(3,2)
逻辑运算符
&& 逻辑与运算
|| 逻辑或运算
! 非
都是短路运算
例如:
int c=5; boolean b = (c<4)&&(c++<4); sout(b); sout(c)
b的结果为false,c的结果为5
因为c<4 结果已经是false 所有后面的(c++)<4直接短路不执行
位运算
A=0011 B=1010 A&B=0010 两个都是1就为1 A|B=1111 有1就为1 A^B=1001 两个相同为0,不同为1 -B=0101 0变1,1变0 << 左移 把数字乘以2 >> 右移 把数字除2
字符串连接符细节
sout(""+a+b); sout(a+b+"");
第一个是拼接,第二个会先把a+b计算了在拼接。
三元运算符
x ? y : z
如果x=true,则结果为y,否则为z
包机制
一般把公司域名倒置作为包名
JavaDoc
生成文档,在命令窗口
javadoc -encoding UTF-8 -charset UTF-8 Doc.java
通过idea生成文档
idea生成JavaDoc文档以及cmd生成Javadoc文档_二哥一直坚持的博客-CSDN博客^v88^control_2,239^v2^insert_chatgpt&utm_term=%E9%80%9A%E8%BF%87idea%E7%94%9F%E6%88%90javadoc&spm=1018.2226.3001.4187
JAVA流程控制
用户交互Scanner
通过Scanner类来获取用户的输入
基本语法:
Scanner s =new Scanner(System.in);
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前一般还要使用hasNext()与hasNextLine()判断是否还有输入的数据
使用next()和hasNext()
//创建一个扫描器对象,用于接受键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("使用next方法接收:"); //判断用户有没有输入字符串 if(scanner.hasNext()){ String str = scanner.next(); System.out.println("输出的内容:"+str); } //io流用完就要关,避免占用资源 scanner.close(); /* next()不能不能得到带有空格的字符串 因为 1.必须读取到有效字符后才能结束输入 2.对有效字符前面的空白,next()方法会自动将其去掉 3.输入了有效字符后,再输入空白会作为分隔符或者结束符 */
使用nextLine()和hasNextLine()
/* nextLine()方法以回车作为结束符 */ //创建一个扫描器对象,用于接受键盘数据 Scanner scanner = new Scanner(System.in); System.out.println("使用nextLine方法接收:"); //判断用户有没有输入字符串 if(scanner.hasNextLine()){ String str = scanner.nextLine(); System.out.println("输出的内容:"+str); } //io流用完就要关,避免占用资源 scanner.close();
选择结构
//1 if(){ } //2 if(){ }else{ } //3 if(){ }else if(){ }else{ } //4 switch(A){ case value : //语句 break;//可选 case value : //语句 braek;//可选 default : //可选 //语句 }
switch(A)中的变量A可以是byte,short,int,char
从java SE 7 开始Switch支持字符串String类型
同时case标签 value必须为字符串常量或者字面量
如果没有break语句,会有穿透现象,即如果第一个case匹配上但是没有break,会把该case以及后面case的内容都会输出
如果没有case匹配上,则输出default里面的内容
循环结构
基本语法
//1 while(){ } //2 do(){ }while() //3 for(){ } //增强for循环,主要用于数组或集合 for(声明语句 ; 表达式){ } //例子,把数组num输出 int[] num={1,2,3} for(int x ; num){ sout(x); }
idea快捷键 100.for 直接生成for循环100次
break,continue,goto
break 用于强制退出循环
continue 用于跳过本次循环,执行下次循环
goto保留关键字,java中的标签和这个类似
out:for(){ for(){ if(){ continue out; } } }
如果if中的条件满足,则直接跳到外部的out:for 这个循环
方法
保持原子性,一个方法完成一个功能
修饰符 返回值类型 方法名(参数类型 参数名){ .. 方法体 .. return 返回值; }
方法重载规则
1.方法名称必须一样
2.参数列表必须不同(个数,类型,或者参数排列顺序不同)
3.返回值类型可以一样
可变参数
在方法声明中,在指定参数类型后加一个省略号(...)
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通参数都必须在它之前声明
类似数组
public static void test(int ... num){ }
递归
递归包含:
递归头:什么时候不调用自身方法,无头会死循环
递归体:什么时候需要调用自身方法
数组
如何声明
dataType[] arrayRefVar; //首选方法 或者 dataType arrayRefVar[]; //效果一样,但不是首选 //创建数组 dataType[] arrayRefVar = new dataType[arraySize];
内存分析
堆:存放new的对象和数组
可以被所有的线程共享,不会存放别的对象引用
栈:存放基本变量类型(会包含这个基本类型的具体数值
引用对象的变量(会存放这个引用在堆里面的具体地址
方法区:可以被所有的线程共享
包含了所有的class和static变量
声明数组A时,在栈中创建A
创建数组A[10],在堆中创建一个A空间
数组赋值,把值存入堆的A空间中
三种初始化
静态初始化
int[] a={1,2};
动态初始化
int[] a =new int[2]; a[0]=1; a[1]=2;
默认初始化
Arrays类
打印数组元素
int [] a={1,2} Arrays.toString(a);//打印数组a Arrays.sort(a);//对a升序排序 Arrays.equals(a);//比较数组中元素是否相等 Arrays.binarySearch(a)//对排好序的数组进行二分查找 Arrays.fill(a,0)//用0填充数组a
冒泡排序
int[] a={1,3,2}; int b=0; for(int i=0;i<a.length-1;i++){ for(int j=0;j<a.length-1-i;j++){ if(a[j+1]>a[j]){ b=a[j]; a[j]=a[j+1]; a[j+1]=b; } } }
稀疏数组
将一个数组中大部分为0,或者同一个数字,利用使用稀疏数组来保存该数组
处理方式:
1:记录下一个有几行几列,有多少个不同值
2:把具有不同值的元素和行列及值记录在一个小规模数组中,从缩小程序的规模
面向对象编程OOP
三大特性:封装,继承,多态
本质:以类的方式组织代码,以对象的方式组织(封装)数据
静态方法直接类名.方法名调用,非静态方法需要先实例化new
静态方法和类一起加载,非静态是类实例化后才有
值传递和引用传递(本质还是值传递,传递对象)
构造器:
一个类即使什么都不写,他也会存在一个构造器方法
名字和类名一致,无返回值
构造器作用:
实例化初始值,使用new关键字必须要有构造器,构造有无参构造和有参构造
如果定义了有参构造必须把无参构造显示定义出来
封装优点;
1.提高系统安全性,保护数据 2.隐藏代码的实现细节 3.统一接口 4.系统的可维护性增加了
继承
idea快捷键 Ctrl+H 打开继承树
在java中所有的类都默认直接或者间接继承object类
私有的无法被继承 private
子类的无参构造方法中默认调用了父类的无参构造方法
调用父类的构造器一定要在子类的前面,放在第一行
super注意:
1.super调用父类的构造方法必须在构造方法的第一个
2。super必须只能出现在子类的方法或者构造方法中
3。super和this不能同时调用构造方法
VS this:
代表的对象不同:this 本身调用者的这个对象 super : 代表父类对象的应用
前提:this没有继承也可以使用 super只能在继承条件下使用
构造方法:this():本类的构造 super():父类的构造
方法的重写
静态方法和非静态方法有很大的区别
静态方法在new的时候与左边的,定义的类型有关:
public class B{ 静态方法test } public class A extends B{ 静态方法test } public class C{ A a = new A(); a.test();//输出的是A里面的test方法 B b = new A();//父类的引用指向子类 b.test();//输出的是B里面的test方法 }
非静态方法才能重写,因为静态方法和类一起加载了
重写需要有继承关系,子类重写父类
1.方法名必须相同
2.参数列表必须相同
3.修饰符,范围可以缩小不能扩大 public》protected》default》private
4.抛出的异常范围只能缩小
重写:子类的方法和父类的必须一致,方法体不同
重写原因:
父类的功能子类不一定需要,或者不一定满足
多态:
一个对象的实际类型是确定的当时可以指向的引用类型就不确定了,父类的引用指向子类
A extends B A s1 = new A() B s2 = new A() Object s3 = new A()
对象可以执行哪些方法,主要看对象左边的类型,和右边关系不大,如上面
s1 可以调用 A中的方法
s2 可以调用B中的方法
如果A,B中都有执行子类重写的
多态的注意事项:
多态是方法的多态,属性没有多态
父类和子类,有联系, 类型转换异常:ClassCastException!
存在条件: 继承关系,方法需要重写 父类引用指向子类的对象 Father f1 = new Son();
instanceof关键字
绑定两个类的关系,是否有继承
有如下类
Object>A>a
Object>A>aa
Object>B
Object object = new a(); //如果x instanceof y x和y之间没有父子关系直接编译不通过 sout(object instanceof a); //结果true 原因:object的实际类型是a和a之间有继承关系 sout(object instanceof A); true sout(object instanceof aa); false a和aa之间没有继承关系 sout(object instanceof object); true sout(object instanceof B); false
类型之间的装换:
//类型之间的装换 父 子 a extends A A obj = new a(); //必须把obj这个类型转换成a 才能使用子类a里面的方法 a obj2 = new a(); obj2.a中的方法 或者强制装换 ((a) obj).子类a中的方法
父类引用指向子类的对象
把子类装换成父类,向上转型
把父类装换成子类,向下转型,强制转换
方便方法的调用,减少重复代码
static
同一个类中,非静态方法可以直接调用静态方法
静态代码块,与类
static{ }
加载的时候执行,永远只执行一次,执行在构造方法前面
静态导入包:
例如调用Math.random()方法可以先静态导入包
import static java.lang.Math.random;
这样就可以直接使用random() 来代替Math.random()
如果使用final定义A这个类,A就无法被继承
抽象类
abstract 修饰的类 为抽象类 抽象方法,只有方法的约束,没有方法的具体实现 抽象类的所有方法,继承了他的子类,必须去实现他的方法,如果子类也是抽象的就子类的子类去实现
不能直接new抽象类,只能通过子类实现
抽象类里面可以有普通方法,抽象方法一定在抽象类中
接口
interface 声明接口的关键字
接口中的所有定义的方法都是抽象的,定义的属性都是常量
需要类实现接口,可以实现多个接口,必须实现接口中的所有方法
类 implements 接口1 implements 接口2
接口不能实例化,没有构造方法
内部类
public class A { public clas B{ 内部类 内部类可以直接访问外部类的私有(private)属性,私有方法. } public static clas B{ 静态内部类 静态的无法直接访问非静态 内部类可以直接访问外部类的私有(private)属性,私有方法. } //匿名内部类的使用,没有名字初始化类,不用将示例保存到变量中 new D().方法; } class D{ 一个java文件中可以有多个class类,但是只能一个public } 方法中也可以创建局部内部类 实例化内部类需要通过外部类 A a = new A(); A.B b = a.new B()
异常
java.lang.Throwable是所有的异常的超类(父类),下面分为两大类Error和Exception
Error类对象由java虚拟机生成并抛出
Exception分支中有一个重要的子类RuntimeException(运行时异常
JVM异常:StackOverFlow 栈溢出
OutOfMemory 内存溢出
面试重点
两者的区别;
Error通常是灾难性的致命的错误,是程序无法控制和处理的,当出现这些异常时,java虚拟机一般会选择终止线程。
Exception通常情况下是可以被程序处理的,并且应该在程序中尽可能的去处理这些异常
异常处理五个关键字try catch finally throw throws
捕获异常:
try{ //try监控区域 代码A// }catch(异常类型E e){ //如果代码A出现异常类型E,则执行下面代码B 代码B }catch(异常类型F f){ //可以捕获多个异常,把大的异常放后面,因为大异常放前面容易被捕获到就不执行后面的catch了 }finally{ //处理善后工作,一定会执行 } try和catch成对出现,finally可写可不写
idea快捷键Ctrl+Alt+T 出现环绕方法
e.printStackTrace();//打印错误的栈信息
抛出异常:
在方法抛出异常:
//如果在方法中无法处理该异常,则在方法上抛出异常 使用throws public void test(int a, int b) throws Exception{ if(b==0){ throw new Exception();//主动抛出异常,一般在方法中使用 } }
自定义异常
用户自定义异常只需要继承Exception类即可
步骤:
创建自定义异常类
在方法中通过throw关键字抛出异常对象
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获处理,否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续下一步
在出现异常方法的调用者中捕获并处理异常
//异常类 public class MyException extends Exception { //传递数>10 private int detail; public MyException(int a){ this.detail = a; } //toString:异常的打印信息 @Override public String toString(){ return "MyException{" + "detail=" + detail + '}'; } } //后面就会其他异常一样的去使用就行