编译型(complie):C和C++速度快;
解释性():
java先编译后解释;属于两者结合;
注释
Annotations:注解;
Comments:注释;
注释:
单行:// 快捷键 Ctrl+/
多行:/**/ 快捷键 Ctrl+Shift+/
文档注释:JavaDoc:/** */ 快捷键
关键字
标识符
组成:字母 数字 下划线 $,数字不能作为开头;大小写敏感;关键字不能作为标识符
数据类型
Java是一个强类型语言:要求变量的使用要严格符合规定,所有变量都必须先定义后使用;
基本类型:(primitive type)
1、 整形 byte 1,short 2,int(默认) 4,long(一般后面加L) 8;
2、 浮点数 float 4,double(默认) 8;BigDecimal(金融计算);
银行不用浮点数的原因:能表现得字长有限,存在舍入误差,只是大约接近但不等于;
3、 字符 char 2;编码:常见的ASCII,utf-8(中文一般用),Unicode;转义字符(\u0000):
\n换行,\r回车,\t制表,\’单引号,\”双引号,\转移反斜杠;
4、 布尔值 Boolean 1位 true , false;
引用类型:
引用类型:(reference type) 类 ,接口,数组;
类型转换
低到高
byte,short,char->int->long->float->double
运算中,不同数据类型的数据先转化为同一类型,然后进行运算;
强制类型转换:【高到低】 (类型)变量名,容易发生内存溢出;
自动类型转换:【低到高】
注意点:
- 不能对布尔类型进行转换;
- 不能把对象类型转换为不相干的类型;
- 在把高容量转换为低容量时需要强制转换;
- 转换的时候可能发生内存溢出,或者精度问题;
变量
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
注意事项:
- 每个变量都有类型,类型可以是基本类型,也可以是引用类型。
- 变量名必须是合法的标识符。
- 变量声明是一条完整的语句,因此每一个声明都必须一分号结束。
变量作用域:
类变量:static 从属于类,和类同时出现和消失;
实例变量:不带static,类里面方法的外面,从属于对象;如果不初始化,就是默认值(0,0.0,0000【16进制u0000】布尔值是false)
局部变量:定义在方法里面的,必须声明和初始化值;
常量(Constant)
定义格式:
final 常量名 = 值;
常量在初始化(initialize)后不能再改变值!不会变的值;
所谓常量可以理解为一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变。
常量一般使用大写字符
修饰符不存在先后之分
命名规则
驼峰原则:单词首字母大写;
- 所有变量、方法、类名:见名知意;
- 类成员变量:首字母小写和驼峰原则;
- 局部变量:首字母小写加驼峰原则;
- 常量:大写字母加下划线;如:MAX_VALUE;
- 类名:驼峰原则;
- 方法名:首字母小写加驼峰原则;
运算符
- 算数运算符:+、-、*、/、%、++、–
- 赋值运算符:=
- 关系运算符:> 、 <、<=、>=、==、!=instanceof
- 逻辑运算符:&&(与)、||(或)、!(非)
- 条件运算符:?:
- 扩展赋值运算符:+=(a+=b等价a=a+b)、-=、*=、/=
包机制
用于区别类名的命名空间;
语法:
package pkg1[.pkg2.[pkg3···]];【必须放在最上面】
一般利用公司域名倒置作为包名;
为了能够使用某一包成员,需要在Java程序中明确导入该包。
方法:
import pkg1[.pkg2···].(classname|*);
JavaDoc帮助文档
JavaDoc命令是用来生成自己API文档的;
参数信息
- @author 作者名
- @version 版本号
- @since 指名最早使用的JDK版本
- @param 参数名
- @return 返回值情况
- @throws 异常抛出情况
**使用:**在命令窗口javadoc【参数: -encoding(编码格式设置) UTF-8 -charset(字符集编码设置) UTF-8 】文件名
Java流控制
Scanner对象
java.util.Scanner是Java5新特征,可以获取用户输入。
语法:
Scanner 对象名 = new Scanner(System.in);
用法:通过Scanner类的netx()与netxLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。
netx()和netxLine()区别
next()
- 一定要读取到有效字符才可以结束输入;
- 对输入有效字符之后遇到空白,next()方法会自动将其去掉;
- 只有输入有效字符才将其后面输入的空白作为分隔符或者结束符;
- next()不能得到带有空格的字符串;
netxLine()
- 以Enter为结束符,返回的是结束之前的所有字符,可以获得空白;
用完之后记得关闭免得浪费资源对象名.close();
//凡是IO流的类如果不关闭会一直占用资源;
switch
switch case 语句判断一个变量与一系列值中某个值是否相等,每个值称为一个分支。
switch语句中的变量类型可以是:
- byte、short、int、char
- 从javaSE7开始
- switch支持字符串String类型了
- 同时case标签必须为字符串常量或者字面量
反编译
循环
while
先判断后执行
while(布尔表达式){
循环内容
};
只要表达式内容为true,就一直循环下去。
我们大多数情况是让循环停下,我们需要一个让表达式失效的方式来结束循环
do···while
先执行后判断
do{
循环内容
}while(布尔表达式);
至少执行一遍
for
for循环语句是支持迭代的一种通用结构,是最有效的最灵活的循环结构;
for循环执行的次数是在执行前就确定的
语法格式
for(初始化;布尔表达式;更新){
循环体
}
注释:
最先执行初始化步骤,可以声明一种类型,可以初始化一个或者多个循环啊控制变量,也可以是空语句,然后检测布尔表达式的值,如果为true,循环体执行。若为false则循环结束,执行最后一次循环后更新循环控制变量;
打印九九乘法表
public class forDome01 {
public static void main(String[] args) {
for (int i = 1; i < 10; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i+"*"+j+"="+(i*j)+"\t");
}
System.out.println();
}
}
增强for循环(for each)
jdk5引入
格式语法
for(声明语句:表达式){循环体}
- 声明语句:声明新的局部变量,该变量的类型必须和数组元素类型匹配其作用域限定在循环语句块,其值于此时的数组元素的值相等;
- 表达式:是要访问的数组名或者是返回数组的方法;
break、continue
**break:**终止循环,也可用在switch语句中;
**continue:**跳出本次循环;
goto
goto关键字在很早就在程序设计语言中出现。尽管goto仍是Java的保留字,但在语言中并未正式使用,在break、continue上我们仍然可以看到goto的影子——带标签的break、continue。
标签:是指后面跟一个冒号的标识符,例如: label:
类
一个类中只能有一个pbulic class但可以有多个class类;
类与对象的关系
-
从认识论的角度考虑是先有对象后又类。对象,是具体事物。类,是抽象的,是对对象的抽象;
-
从代码运行的角度考虑是先有类后有对象,类是对象的模板。
-
类是一种抽象的数据类型,它是对某一类事物的整体描述/定义,但并不代表某一个具体的事物;
-
对象是抽象概念的具体实例;
-
类实例化之后会返回一个自己的对象;
创建与初始化对象
使用new关键字来创建对象
使用new关键字来创建的时候,除了分配内存空间外,还会给创建好的对象进行默认初始化以及对类中构造器的调用;
类中构造器
- 类中构造器也称构造方法,是在创建对象的时候必须调用的,
- 特点:必须和类的名字相同;
- 特点:必须没有返回值,也不能写void;
作用:
- 使用new关键字,本质还是调用构造器;
- 一般用来初始化值;
方法
方法是语句的集合,在一起执行一个功能
- 方法是解决一类问题的步骤有序集合
- 方法包括类或者对象
- 方法在程序中被创建,在其他地方被引用
- 类似于其它语言中的函数
方法的设计原则:
方法的本意是功能模块,就是实现某个功能的语句块的集合,我们设计的时候,最好保持方法的原子性,就是一个方法实现一个功能,在这样有益于我们后期的扩展;
命名规则:
首字母小写加驼峰命名法;
格式:
修饰符 返回值类型 方法名(参数类型 参数1,参数类型 参数2) 异常抛出 { 方法体}
方法名:注意规范就OK 见名知意s ;
方法调用:
后人之前人,前人不知后人;(非静态可以访问静态,静态不能访问非静态)
- 静态方法:可用类名.方法名调用;和类一起加载的,
- 非静态方法:需要实例化这个类(new),对象名.方法名;与对象有关的,类实例化之后才存在;
- 形参和实参:实际参数和形式参数类型要对应;
- 值传递和引用传递:Java中都是值传递;**值传递:**传递的是参数的副本,修改时只修改了副本并没有对参数本身进行修改;**引用传递:**传递的是参数的地址,修改参数时是直接对原始数据进行修改;
- this关键字:谁调用指的就是谁;
对象名.方法名(参数列表):
调用时方法有返回值时,要定义一个变量接收该值或者当作一个值使用;
值传递
- 形式参数类型是基本数据类型,方法调用时,实际参数把它的值传递给对应的形式参数,形式参数只是用实际参数的值初始化自己的存储单元内容,是两个不同的存储单元,所以方法执行中形式参数的值改变不影响实际参数的值;
引用传递
- 形式参数类型是引用数据类型参数,也称为传地址,方法调用时,实际参数是对象或者数组,这时实际参数和形式参数指向同一个地址,在方法执行中,对形式参数的操作实际上是对实际参数的操作,这个结果在方法结束后被保留了下来,所以方法执行中形式参数的改变将会影响实际参数;
方法的重载
- 方法名称相同
- 参数不同(个数,类型,参数排序等有不同即可)
- 返回值类型可同可不同
- 仅仅是返回值类型不同不足以成为重载
实现理论:编译器会根据 参数类型、个数 等自动匹配方法。
方法的重写
- 重写都是方法的重写和属性无关;
- 有子父类(或者实现)的关系才能重写,子类重写父类方法,重写接口中方法;
- 重写跟静态方法没有任何关系,只和非静态方法有关;
特点
- 方法名必须相同,参数列表必须相同,修饰符范围可以扩大,但不能缩小;
- 方法体不同
- 修饰符是 Private则不能重写;抛出异常的范围,可以被缩小不能扩大;
不能被重写的方法类型
- Static 方法:它是属于类的,不属于实例;
- final 常量:不可被修改;
- private 方法:私有的;
命令行传参
main方法是可以传递参数的
可变参数
- jdk1.5开始,Java支持传递同类型的可变参数的一个方法
- 在方法声明中,在指定参数类型后加一个省略号(···)
- 一个方法中只能指定一个可变参数,他必须是方法的最后一个参数,任何普通参数必须在他之前声明;
格式:
修饰符 返回值类型 方法名(参数类型 参数1,参数类型... 参数2){ 方法体}
递归
- A方法自己调用自己
- 递归头:什么时候不调用自身方法。如果没有头,将陷入死循环;
- 递归体:什么时候需要调用自身方法。
- 基数小的可以用递归,基数大的容易崩溃;
- Java栈机制,执程序压栈执行,基数大的栈深影响机器性能
值传递,参数传递
java是值传递
内存分析
Java内存
-
**堆:**存放new的对象和数组,可被所有线程共享,不会存放别的对象引用
-
**栈:**存放基本变量类型(包含这个基本类型的具体数值);
存放引用对象的变量(会存放这个引用在堆里面的具体地址)
-
方法区:可以被所有的线程共享,包含所有的class和static变量
数组
**定义:**相同数据类型的有序集合,其中每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们;
声明和创建
声明
第一种:类型名[] 数组名;//定义 推荐
第二种:类型名 数组名[];//C和C++中的写法,早期为了让程序员能掌握,
Java使用new操作符来创建数组,
数组名 = new 类型名(要和定义数组的类型相同)[容量];
第三种:类型名[] 数组名 = new 数组类型[容量]
数组长度
- 用 数组名.length 获取数组长度
- 下标的合法区间是:[0,length-1];
- 如果越界会报数组下标越界异常(ArrayIndexOutOfBoundsException)
初始化
静态初始化:数组类型[] 数组名 = {元素,元素,···};//数组容量等于元素个数固定不可变
**动态初始化:**类型名[] 数组名 = new 数组类型[容量];后面手动赋值;
数组的四个基本特点:
- 长度是确定的,数组一旦被创建,它的大小即使不可改变的;
- 元素类型必须相同,不能出现混合类型;
- 数组元素可以是任何类型包括基本类型和引用类型;
- 数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中;
多维数组
数组是另外一个数组的元素;
Arrays类
- 数组的工具类 Java.util.Arrays包下,可以对数组对象进行一些基本操作。
- Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接用类名进行调用(也可以使用对象来调用)
Arrays常用功能
- 给数组赋值:用 fill 方法;
- 对数组排序:通过 **sort **方法,按升序;
- 比较数组:通过 equals 方法比较数组中元素是否相等;
- 查找数组元素:通过 binarySearch 方法能对排序好的数组进行二分查找法操作;
冒泡排序
-
**原理:**比较相邻元素大的放后面,每次循环过后少一次排序;
-
代码简单,两层循环,外层冒泡轮数,里层依次比较;
-
时间复杂度O(n2);
稀疏数组
- 当一个数组中大部分元素为0,或者为同一个数值时,可以使用稀疏数组来保存;
- 稀疏数组的处理方式:记录数组一共几行几列,有多少不同的值;把具有不同值的元素和行列记录在一个小规模数组中从而缩小程序规模;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-ZHZzZB2I-1626408112655)(D:\周林\Pictures\Saved Pictures\QQ截图20210703223452.png)]
面向对象编程(OOP)
面向对象:OO;
面向过程&面向对象
面向过程:
- 步骤清晰,第一步,第二步······;适合处理一些简单的问题;
面向对象:(**本质:**以类的方式组织代码,以对象的方式组织(封装)数据)
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后才对某个分类下的细节进行面向过程的思索;
- 面向对象适合解决复杂的问题,适合处理需要多人协作问题;
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们我需要使用面向对象的思路来分析整个系统。但是具体到围观操作,仍然需要面向过程的思路去处理;
高内聚,低耦合
我们程序设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合仅暴露少量的方法给外部使用;
三大特性
封装:
- (数据的隐藏) 属性私有,get/set。简单来说就是该露的露,该藏得藏;
- 通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息的隐藏
封装的意义:
- 提高程序的安全性,保护数据;
- 隐藏代码的实现细节;
- 统一接口;
- 系统可维护增加了;
继承
子类继承了父类就会有父类的所有方法(私有的除外)
继承的本质是对某一批类的抽象,从而实现对现实世界的更好建模。
extends的意思是“扩展”。子类是父类的扩展;
Java中类中只有单继承,没有多继承;(一个儿子只能有一个爸爸,一个爸爸可以有多个儿子)
Java中所有的类都默认直接或者间接继承Object类;
- 继承是类和类之间的一种关系。除此之外,类和类之间的关系还有依赖,组合,聚合等;
- 继承关系的两个类,一个是子类(派生类),一个是父类(基类)。子类继承父类,使用关键字extends来表示;
- 子类和父类之间,从意义上讲应该具有“is a”的关系;
- 被Fina修饰的类不可被继承,Final之后断子绝孙;
Super
- Super调用父类,this访问本类,this代表调用者本身;
- Super调用父类的构造方法,必须在构造方法的第一个;
- Super只能出现在子类的方法或者构造方法中;
- Super 和 this不能同时调用构造方法;
多态
- 方法的多态;
- 存在条件:继承关系,方法重写,父类的引用指向子类对象;
- 父类的引用指向子类;方法的调用只和定义的数据类型有关;
- 一个类的实际类型是确定的,可以指向的引用类型就是不确定了;
- 子类重写了父类的方法调用时调用子类重写的方法,没有重写则向父类找;
- 父类型不能调用子类独有的方法;
instanof (类型转换) 引用类型;判断一个对象是什么类型;
子类转为父类,向上转型;父类转为子类,向下转型,需要强制类型转换,可能会丢失一些方法(类似于基本类型转换丢失精度);
static
- 静态变量能被整个类的实例共享;
//匿名代码块,一般用来赋初值,和对象一起加载
{
//匿名代码块
}
//静态代码块,静态代码块和类一起加载,只加载一次
static{ //静态代码块}
抽象类
一般来说作为一种约束使用,规定好方法名;
- 通过abstract修饰的类(方法),称为抽象类(方法);
- 继承抽象类,就必须重写抽象类里的所有抽象方法;如子类也是抽象类则不用;
- 类是单继承,接口可以多继承;
- 抽象方法必须,存在抽象类中;抽象类中可以存在普通方法;
- 抽象类不能被new出来,必须使用子类来实现;
接口
关键词interface,接口都必须用实现类,接口中没有构造方法;
- 普通类:只有具体实现;
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范!自己无法写方法~专业约束;
接口就是规范或者是契约,定义的是一组规则,体现了现实世界中的法律,必须遵守;
接口的继承
关键字:implements
- 接口是多继承;
- 继承接口的类必须重写接口中的方法;
异常
-
java把异常当作对象来处理,并定义了一个基类Java.lang,Throwable作为所有异常的超类;
-
在Java API中已经定义了很多异常类,这些异常类分为两大类,错误Error和异常Exception;
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OgxdikFu-1626408112657)(D:\周林\Pictures\Saved Pictures\QQ截图20210709091337.png)]
- 软件程序在运行过程中,非常可能遇到的问题,我们叫之类,英文:Exception意思是例外;
Exception
异常一般由程序逻辑错误一起的,程序应该从逻辑角度尽可能的避免这些异常的发生;
检查时异常
这些异常在编译时就不能被忽略;
运行时异常
运行时异常是可能被程序员避免的异常,与检查时异常相反,运行时异常可以在编译时被忽略;
错误(Error)
Error类对象是由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关;一旦发生Java虚拟机(JVM)一般都会终止线程;
Error和Exception的区别
- Error通常是灾难性的致命错误,是程序无法控制和处理的,当出现这些异常时,Java虚拟机(JVM)一般会选择终止程序;
- Exception通常情况下是可以被程序处理的,并且在程序中应该尽可能的去处理这些异常;
异常处理机制
异常处理的五个关键字
try:(处理)catch:(捕获)finally:(无论怎样都会执行)throw、throws(抛出异常)
抛出异常
- 主动抛出异常一般在方法中使用;
throw new 异常类型();
- 在方法上主动抛出异常;
方法名 () throws 异常类型{ }
捕获异常
- 可以捕获多个异常,如catch(){}catch(){},但参数需要遵循从小到大;
- IDEA 自动生成Ctrl+Alt+T;
try{//监控区域
//可能发生异常的代码;
}catch(参数类型 参数){
//catch(想要捕获的异常类型)捕获异常; //处理办法;
}finally{
//处理善后工作
}//finally可以没有,常用于资源关闭之类的;
自定义异常类
- 自定义类继承Exception;
- 在方法中通过throws关键字抛出异常类对象;
- 如果在当前抛出的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明出通过throws关键字指明要抛出给方法调用者的异常,继续进行下一2步操作;
- 在出现异常方法的调用者中捕获异常并处理;
异常经验小结
- 处理运行时异常时 ,采用逻辑去合理规避同时辅助 try-catch处理;
- 在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常;
- 对于不正确的代码,可以加上try-catch,处理潜在异常;
- 尽量去处理异常,切记只是简单的调用 printStackTrace()去打印输出;
- 具体如何处理异常,要根据不同的业务需求和异常类型去决定;
- 尽量添加finally语句块去释放占用的资源;