目录
单行注释://
多行注释:/* 这是一个多行注释 */
文档注释:/** 文档注释 */
Java所有的组成部分都需要名字。类名、变量名以及方法名都被称为标识符。
所有的标识符都应该以字母,美元符,或者下划线开始
首字符之后可以是字母,美元符,下划线或者数字的任何字符组合
不能使用关键字作为变量名或者方法名
标识符区分大小写
关键字不能用于起名字,相应关键字如下表:
abstract | assert | boolean | break | byte |
---|---|---|---|---|
case | catch | char | class | const |
continue | default | do | double | else |
enum | extends | final | finally | float |
for | goto | if | implements | import |
instanceof | int | interface | long | native |
new | package | private | protected | public |
return | strictfp | short | static | super |
switch | synchronized | this | throw | throws |
transient | try | void | volatile | while |
Java的数据类型分为两大类:
基本类型(primitive type):包括数值类型和boolean类型
数值类型:包括整数类型、浮点类型和字符类型
整数类型有:byte、short、int、long
浮点类型有:float、double
字符类型有:char
boolean类型:占1位其值只有true和false两个
(小知识补充):
位(bit):是计算机内部数据存储的最小单位
字节(byte):是计算机中数据处理的基本单位,习惯上用大写B来表示
1B(byte,字节)=8bit(位)
字符:是指计算机中使用的字母、数字、字和符号
1024B=1KB
1024KB=1M
1024M=1G
引用类型(reference type):类、接口、数组
相应知识拓展:
//整数拓展:二进制0b开头 八进制0开头 十六进制0x开头 int i =10; int j=010; int m=0x10; System.out.println(i); System.out.println(j); System.out.println(m); //结果为:10、8、16 //============================================ //浮点数拓展: //float double float f=0.2f;//0.2 double d=2.0/10;//0.2 System.out.println(f==d);//结果为false ? float f1=234567896543321345f; float f2=f1+1; System.out.println(f1==f2);//结果为true ? /*这是因为计算机存储浮点数的方式并不是精确的十进制数,而是它的二进制近似值,这里,f 是 float 类型,而 d 是 double 类型。由于 double 的精度高于 float,d 的值可能是一个更精确的近似值。因此,f 和 d 在计算机中被存储为不同的值,导致 f == d 返回 false。 //这里,尽管 f1 是一个非常大的数,但由于浮点数的精度问题,当你给这个数加1时,加的结果可能是精确的整数,而不是这个小数部分。这导致了 f1 和 f2 实际上存储了相同的值,因此 f1 == f2 返回 true。*/ //所以宝子们用浮点数进行比较的时候一定要注意了!!! ? //转义字符 /* \n - 换行符,用于在输出中创建新的一行。 \t - 制表符,用于在输出中创建制表符。 \\ - 反斜杠,用于表示一个字面上的反斜杠字符。 \" - 双引号,用于表示一个字面上的双引号字符。 \' - 单引号,用于表示一个字面上的单引号字符。 \b - 退格符,用于在输出中退回一个字符的位置。 \r - 回车符,用于在输出中创建回车。 \f - 换页符,用于在输出中创建换页。 \uXXXX - 用于表示一个Unicode字符,其中XXXX是四个十六进制数字。*/
运算中,不同类型的数据先转化为同一类型,然后进行运算
由低到高(容量,字节大小):
byte,short,char--->int--->long--->float--->double
其中小数的优先级一定大于整数
int i=128; byte b=(byte)i;//内存溢出,byte的最大容量为127 System.out.println(i); System.out.println(b); //结果为:128、-128这是因为其内存溢出, //所以在进行强制类型转换的时候要避免内存溢出。 //强制转换格式:(类型)变量名 由高到低 //自动转换:由低到高 //不能对布尔值进行转换 //在强制转换的时候还要注意精度问题
Java是一种强类型语言,每个变量都必须声明其类型
Java变量是程序中最基本的存储单元,其要素包括变量名,变量类型和作用域。
格式:
数据类型 变量名 = 值; 其中可以使用逗号隔开来声明多个同类型变量
注意事项:
每个变量都有类型,类型可以是基本类型,也可以是引用类型
变量名必须是合法的标识符
变量声明是一条完整的语句,因此每一个声明都必须以分号结束
变量作用域:
类变量
实例变量
局部变量
public class Demo{ //一个类 ? ?//类变量:static 从属于类 ? ?static double x=8888; ? ? ? ?//属性:变量 ? ? ? ?//实例变量(类里面方法外边):从属于对象,可以不用初始化,有其默认值 ? ?//布尔值:默认是false ? ?String name; ? ? ? ?//main方法 ? ?public static void main(String[] args){ ? ? ? ?//局部变量(在方法内):使用前必须声明和初始化值,其生命周期在此方法内 ? ? ? ?int i=88; ? ? ? ?System.out.println(i); ? ? ? ? ? ? ? ?//如何用实例变量 ? ? ? ?//变量类型 变量名字=new Demo(); ? ? ? ?Demo demo = new Demo(); ? ? ? ?System.out.println(demo.name) ? } ? ?//还可定义其他方法如 ? ?public void test(){ ? ? ? ? ? } }
常量
所谓常量可以理解为一种特殊的变量,它的值被设定后,在程序运行过程中不允许被改变
格式:
final 常量名=值;
final double PI=3.14;
常量名一般使用大写字符
变量的命名规范:
所有变量、方法、类名:见名知意
类成员变量:首字母小写和驼峰原则:除了第一个单词以外,后面的单词首字母大写
局部变量:首字母小写和驼峰原则
常量:大写字母和下划线
类名:首字母大写和驼峰原则
方法名:首字母小写和驼峰原则
算术运算符:+、-、*、/、%、++、--
赋值运算符:=
关系运算符:> < >= <= == != instanceof
逻辑运算符:&& || !
位运算符:& | ^ ~ >> << >>>
条件运算符:? :
扩展赋值运算符:+= -= *= /=
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间
包语句的语法格式:
package pkg1[.pkg2[.pkg3......]];
一般利用公司域名倒置作为包名
Javadoc命令是用来生成自己API文档的
参数信息:
@author 作者名
@version 版本号
@since 指明需要最早使用的jdk版本
@param 参数名
@return 返回值情况
@throws 异常抛出情况
其生成API相关语句:
javadoc -encoding UTF-8 -charset UTF-8 类名.java
可以通过Scanner类来获取用户的输入
基本语法:
Scanner s=new Scanner(System.in);
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前我们一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据。
next():
一定要读取到有效字符后才可以结束输入
对输入有效字符之前遇到的空白,next()方法会自动将其去掉
只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符
next()不能得到带有空格的字符串
nextLine():
以Enter为结束符也就是说nextLine()方法返回的是输入回车之前的所有字符
可以获取空白
用完可以关掉Scanner,节约资源:scanner.close();
Java的基本结构就是顺序结构,除非特别指明,否则就按照顺序一句一句执行
顺序结构是最简单的算法结构
if单选择结构
语法:
if(布尔表达式){
如果布尔表达式为true将执行的语句
}
if双选择结构
语法:
if(布尔表达式){
如果布尔表达式为true将执行的语句
}else{
如果布尔表达式为false将执行的语句
}
if多选择结构
语法:
if(布尔表达式1){
如果布尔表达式1为true将执行的语句
}else if(布尔表达式2){
如果布尔表达式2为true将执行的语句
}else if(布尔表达式3){
如果布尔表达式3为true将执行的语句
}else{
如果以上布尔表达式都不为true将执行的语句
}
嵌套的if结构
if(布尔表达式1){
如果布尔表达式1为true将执行的语句
if(布尔表达式2){
如果布尔表达式2为true将执行的语句
}
}
switch多选择结构
语法:
switch(expression){ ? ?case value: ? ? ? ?//语句 ? ? ? ?break;//可选 ? ?case value: ? ? ? ?//语句 ? ? ? ?break;//可选 ? ?//可以有多个case语句 ? ?default://可选 ? ? ? ?//语句 }
while循环
while是最基本的循环,它的结构为:
while(布尔表达式){
循环内容
}
只要布尔表达式为true,循环就会一直执行下去
do...while循环
do...while循环和while循环相似,不同的是,do...while循环至少会执行一次
do{
//代码语句
}while(布尔表达式);
for循环
for循环执行的次数是在执行前就确定的,语法格式如下:
for(初始化;布尔表达式;更新){
//代码语句
}
增强for循环
for(声明语句:表达式){
//代码句子
}
示例如下:
int [] numbers={1,2,3,4};//定义了一个数组 //遍历数组的元素 for(int x:numbers){ ? ?System.out.println(x); } //输出结果为1,2,3,4
break在任何循环语句的主体部分,均可用break控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句。(break语句也在Switch语句中使用)
continue语句用在循环语句体中,用于终止某次循环过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定。
Java方法是语句的集合,它们在一起执行一个功能
方法是解决一类问题的步骤的有序组合
方法包含于类或对象中
方法在程序中被创建,在其他地方被引用
设计方法的原则:最好保持方法的原子性,就是一个方法只完成一个功能。
方法包含一个方法头和方法体:
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值
}
修饰符:这是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型,如:public ,static......
方法调用
调用方法:对象名.方法名(实参列表)
Java支持两种调用方法的方式,根据方法是否返回值来选择
当方法返回一个值的时候,方法调用通常被当做一个字,如:
int s=max(23,45);
如果方法返回值是void,方法调用一定是一条语句
System.out.println("Hello,baozi");
拓展:Java为值传递
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法的重载的规则:
方法名称必须相同
参数列表必须不同(个数不同,或类型不同,参数排列顺序不同等)
方法的返回类型可以相同也可以不相同
仅仅返回类型不同不足以成为方法的重载
实现理论:
方法名称相同时,编译器会根据调用方法的参数个数,参数类型等去逐个匹配,以选择对应的方法,如果匹配失败,则编译器报错。
有时候你希望运行一个程序的时候再传递给它消息,这要靠传递命令行参数给main()函数实现。
举例如下:
在方法声明中,在指定参数类型后加一个省略号(...)
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在它之前声明。
举例如下:
递归就是:A方法调用A方法!就是自己调用自己
递归结构包括两个部分:
递归头:什么时候不调用自身方法。如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法
举例如下(以求阶乘为例):
数组是相同类型数据的有序集合
数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问它们。
声明数组变量的语法:
dataType[] arrayRefvar; //首选的方法 //举例:int[] nums 声明 // nums=new int[10] 创建 dataType arrayRefVar[];//效果相同
Java语言使用new操作符来创建数组,如下:
dataType[] arrayRefvar=new dataType[arraySize] //举例:int[] nums=new int[10] 声明+创建
数组的元素是通过索引访问的,数组索引从0开始。
静态初始化:创建+赋值
int[] a ={1,2,3,4};
动态初始化:包括默认初始化
int[] b=new int[10];
b[0]=1;
数组的四个基本特点:
其长度是确定的。数组一旦被创建,它的大小就是不可以改变的。
其元素必须是相同类型,不允许出现混合类型
数组中党的元素可以是任何数据类型,包括基本类型和引用类型
数组变量属于引用类型,数组也可以看成是对象,数组中的每个元素相当于该对象的成员变量。数组本身就是对象,Java中对象是在堆中的,因此数组无论保存原始类型还是其他对象类型,数组对象本身是在堆中的。
普通的For循环
For-Each循环
数组作方法入参
数组作返回值
多维数组可以看成是数组的数组,比如二维数组就是一个特殊的一维数组,其每一个元素都是一个一维数组
二维数组:
int a [][]=new int[2][5];//可以看成一个二行五列的数组
查看JDK帮助文档
Arrays类中的方法都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
记录数组一共有几行几列,有多少个不同值
把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
举例如下(以棋盘为例):
public class Main { public static void main(String[] args) { //创建一个二维数组11*11 int[][] array1=new int[11][11]; //0:无棋子 1:黑子 2:白子 array1[1][2]=1; array1[2][3]=2; System.out.println("棋盘数组为:"); for(int[] x:array1){ for (int y:x){ System.out.print(y+"\t"); } System.out.println(); } System.out.println("=========================="); //转换为稀疏数组保存 int sum=0; for(int i=0;i<11;i++){ for (int j=0;j<11;j++){ if(array1[i][j]!=0){ sum++; } } } System.out.println("有效值的个数为:"+sum); //创建一个稀疏数组 int[][] array2=new int[sum+1][3]; array2[0][0]=11; array2[0][1]=11; array2[0][2]=sum; //将非零的值存放到稀疏数组中 int count=0; for(int i=0;i<array1.length;i++){ for (int j=0;j<array1[i].length;j++){ if(array1[i][j]!=0){ count++; array2[count][0]=i; array2[count][1]=j; array2[count][2]=array1[i][j]; } } } //输出稀疏数组 System.out.println("稀疏数组为"); for (int i=0;i<array2.length;i++){ for(int j=0;j<3;j++){ System.out.print(array2[i][j]+"\t"); } System.out.println(); } } }
其运行结果如图所示:
面向对象编程(Object-Oriented Programming, OOP)
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
三大特征:封装、继承、多态
从认识论角度考虑是先有对象后有类。对象,是具体的事物。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后有对象。类是对象的模版
break与return的区别:
break跳出Switch,结束循环
return结束方法,返回一个结果
方法的调用:
静态方法(加了static):
在另一个类中调用该方法可直接 类名.方法名()调用
其举例如下:
非静态方法
非静态方法不能直接调用需要先实例化
其举例如下:
其他一些特殊案例
值传递和引用传递
类是一种抽象的数据类型,他是对某一类事物整体的描述/定义,但是并不能代表某一具体的事物。
对象是抽象概念的具体实例
使用new关键字创建对象:
使用new关键字创建的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化以及对类中构造器的调用。
其具体例子如下:
类中的构造器也称为构造方法,是在进行创建对象的时候必须要调用的。并且构造器有以下两个特点:
必须和类的名字相同
必须没有返回类型,也不能写void
其构造器应用如下:
封装:
通常,应禁止直接访问一个对象中数据的实际表示,而应通过操作接口来访问,这称为信息隐藏
属性私有:get/set
继承:
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
extends的意思是扩展。子类是父类的扩展
JAVA中类只有单继承,没有多继承。
父类中带有private的属性是无法继承的
super可以调用父类的属性和方法,但若要调用父类的构造器,必须要在子类构造器的第一行
super注意点:
super调用父类的构造方法,必须在构造方法的第一个
super必须只能出现在子类的方法或者构造方法中
super和this不能同时调用构造方法
VS this:
代表的对象不同:
this:本身调用者这个对象
super:代表父类对象的引用
前提:
this:没有继承也可以使用
super:只能在继承条件下才可以使用
构造方法:
this():本类的构造
super():父类的构造
方法重写:
需要有继承关系,子类重写父类的方法
方法名必须相同
参数列表必须相同
修饰符:范围可以扩大但不能缩小:public>protected>Default>private
抛出的异常:范围可以被缩小但不能扩大:ClassNotFoundException----->Exception(大)
重写,子类的方法和父类必须一致,方法体不同
为什么要重写:
父类的功能子类不一定需要,或者不一定满足
快捷键:Alt+insert: override
多态:
即同一方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多。
多态存在的条件:
有继承关系
子类重写父类方法
父类引用指向子类对象
注意:多态是方法的多态,属性没有多态性。
案例如下:
instanceof: 引用类型,判断一个对象是什么类型 ,可以判断两个类之间是否存在父子关系
强制转换:
static:
static { //静态代码块,只执行一次 }
抽象类:
abstract修饰符可以用来修饰方法也可以修饰类,如果修饰方法,那么该方法就是抽象方法;如果修饰类,那么该类就是抽象类。
抽象类中可以没有抽象方法,但是有抽象方法的类一定要声明为抽象类。
抽象类,不能使用new关键字来创建对象,它是用来让子类继承的
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的
子类继承抽象类,那么就必须要实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
接口:
普通类:只有具体实现
抽象类:具体实现和规范都有
接口:只有规范
代码举例如下:
内部类:
内部类就是在一个类的内部定义一个类
成员内部类
静态内部类
局部内部类
匿名内部类
异常指程序运行中出现的不期而至的各种状况,如:文件找不到、网络连接失败、非法参数等。
异常发生在程序运行期间,它影响了正常的程序执行流程
检查性异常
运行时异常
错误
使用Java内置的异常类可以描述在编程出现的大部分异常情况。除此之外,用户还可以自定义异常。用户自定义异常类,只需要继承Exception类即可。
在程序中使用自定义异常类,大体可分为以下几个步骤:
创建自定义异常类
在方法中通过throw关键字抛出异常对象
如果在当前抛出异常的方法中处理异常,可以使用try-catch语句捕获并处理;否则在方法的声明处通过throws关键字指明要抛出给方法调用者的异常,继续进行下一步操作。
在出现异常方法的调用者中捕获并处理异常
应用中总结:
处理运行时异常时,采用逻辑去合理规避同时辅助try-catch处理
在多重catch块后面,可以加一个catch(Exception)来处理可能会被遗漏的异常
对于不确定的代码,也可以加上try-catch,处理潜在的异常
尽量去处理异常,切忌只是简单地调用printStackTrace()去打印输出
具体如何处理异常,要根据不同的业务需求和异常类型去决定
尽量添加finally语句块去释放占用的资源