1.1、常用Dos命令
切换盘符:直接输入“盘符:+回车”;
ipconfig 查看IP地址
ipconfig/all 查看更详细的网络信息,这个详细信息中包括网卡 的物理地址,例如:70-8B-CD-A7-BA-25,这个物理地址具有全球唯一性。物理地址通常叫做MAC地址。
1.2、什么是相对路径和绝对路径
相对路径:
从路径形式上来看,相对路径是一定不会以盘符开始的。
相对路径:相对路径一定是相对于当前所在“位置”而言的。
绝对路径:
在windows操作系统中凡是路径起点是盘符的都是绝对路径
1.3、怎么查看两台计算机是否可以正常通信?
ping命令
语法格式:
ping IP地址
ping 域名
ping www.baidu.com
ping 61.135.169.121 (61.135.169.121是百度的IP地址)
ping 61.135.169.121 -t (-t参数表示一直ping)
一直ping的目的可以查看网络是否稳定。
在一个DOS命令窗口中如果有一个命令一直在执行,想强行终止怎么办?
ctrl + c 组合键
http://www.baidu.com 可以打开百度(这种方式比较方便,域名更容易记忆。)
http://61.135.169.121 也可以打开百度
域名底层最终还是会被解析成IP地址的形式。
1.1、计算机编程语言发展史?
第一代语言:机器语言
程序员直接编写二进制,一串二进制代码,计算机是由电流驱动的,电流只能表示两种状态:正、负。
而正可以对应1,负可以对应0.
10010010101010...这些二进制码正好和自然世界中的十进制存在转换关系。
所以很巧妙的是:计算机可以模拟现实世界当中的事物。
机器语言时期非常具有代表性的就是:打孔机。
缺点:
纸带不容易保存
另外打孔的时候是人为操作的,孔有可能打错了。孔打错了纸带就废了。
第二代语言:低级语言
非常具有代表性的:汇编语言。
汇编语言比机器语言更接近人类自然语言。
但是汇编语言还是需要专业人士进行开发,一般人拿到汇编语言也读不懂。
第三代语言:高级语言
高级语言完全接近人类自然语言,具有代表性的:
C语言:面向过程的
C++语言:一半面向过程,一半面向对象
Java语言:完全面向对象(java语言底层实际上是C++实现的。)
Python语言:面向对象
....
计算机编程语言是什么?
是一个组织制定的一套固定的语法规则,你可以学习这套语法规则,然后通过这套语法规则和计算机交互。
1.1、JDK、JRE、JVM三者之间的关系
JDK:Java Development Kit开发工具箱
JRE:Java Runtime Enverionment运行环境
JVM:Java Virtual Machine虚拟机
JDK包括JRE,JRE包括JVM。
JVM是不能独立安装的。没有单独的JVM安装包。
JRE和JDK都是可以独立安装的。有单独的JDK安装包。也有单独的JRE安装包。
安装JDK的时候:JRE就自动安装了,同时JRE内部的JVM也就自动安装了。安装JRE的时候:JVM也就自动安装了。
问题:
假设你在软件公司开发了一个新的软件,现在要去客户那边给客户把
项目部署一下,把项目跑起来,你需要安装JDK吗?
只需要安装JRE就行了。JRE体积很小,安装非常便捷快速。
问题:
为什么安装JDK的时候会自带一个JRE?
因为java程序员开发完程序之后,要测试这个程序,让这个程序运行起来,需要JRE。
所以JDK安装的时候内部自带一个JRE。
1.2、到目前为止,我们接触过的重点术语,总结一下:
Java体系的技术被划分为三大块:
JavaSE:(Java Platform,Standard Edition)标准版
JavaEE:(Java Platform,Enterprise Edition)企业版
JavaME:(Java Platform,Micro Edition)微型版
安装JDK之后:
JDK:java开发工具箱
JRE:Java运行环境
JVM:Java虚拟机
1.3、对Java的加载与执行的理解(理论比较重要)
1个java源文件是可以编译生成多个class文件的。最终运行的是class文件。
问题:字节码文件是二进制文件吗?
字节码文件不是二进制文件。如果是二进制的话,就不需要JVM了。因为操作系统可以直接执行二进制。
1.1、配置JAVA_HOME
1、在系统变量中,添加一个环境变量
变量名:JAVA_HOME
变量值:jdk安装路径,不带bin目录
2、在path环境变量中,使用%JAVA_HOME%动态的将JAVA_HOME的变量的值给取出来
%JAVA_HOME% == D:\developTools\java\jdk1.8
拼接bin目录,形成了
%JAVA_HOME%\bin == D:\developTools\java\jdk1.8\bin
1.2、classpath环境变量的作用是什么?
是给类加载器指路的。
在没有配置环境变量classpath的时候,默认从当前路径下加载。
如果配置了环境变量classpath的话,就只能从指定的路径下加载了。
1.1、什么是标识符,标识符可以标识什么?
一句话搞定:凡是程序员自己有权利命名的单词都是标识符。
可以标识:
类名
方法名
变量名
接口名
常量名
......
1.2标识符命名规则
规则1:标识符只能由数字、字母(包括中文)、下划线_、美元符号$组成,不能含有其它符号。
规则2:标识符不能以数字开头
规则3:关键字不能做标识符。例如:public class static void ,关键字是不能做标识符的。
规则4:标识符是严格区分大小写的。大写A和小写a不一样。
规则5:标识符理论上是没有长度限制的。
1.3、标识符命名规范
规范1:见名知意(这个标识符在起名的时候,最好一看这个单词就知道啥意思。)
规范2:遵循驼峰命名方式,什么是驼峰(一高一低,一高一低...)
驼峰有利于单词与单词之间很好的进行分隔
BiaoShiFuTest,这个很好,一眼就能看出来是4个单词。
规范3:类名、接口名有特殊要求
类名和接口名首字母大写,后面每个单词首字母大写。
StudentTest、UserTest ,这是类名、接口名。
规范4:变量名、方法名有特殊要求
变量名和方法名首字母小写,后面每个单词首字母大写。
nianLing(NianLing这样就不符合了。)
mingZi(MingZi这样也不符合了。)
规范5:所有“常量”名:全部大写,并且单词和单词之间采用下划线衔接。
USER_AGE :用户年龄
MATH_PI:固定不变的常量3.1415926.....
1.4、什么是关键字
在SUN公司开发Java语言的时候,提前定义好了一些具有特殊含义的单词,这些单词全部小写,具有特殊含义,不能用作标识符。
1.5、什么是变量
变量就是一个存数据盒子。(盒子大小谁来决定啊?数据类型)
在内存中的最基本的存储单元。
存数据用的,而且这个数据是可变的,所以叫做变量。
变量的三要素:数据类型、变量名、值(值就是数据,就是字面量)
java中的变量必须先声明,再赋值才能访问(必须手动赋值。)
变量分为局部变量和成员变量,成员变量又分为实例变量和静态变量(类级别的)
1.1、数据类型的作用
数据类型用来声明变量,程序在运行过程中根据不同的数据类型分配不同大小的空间。
1.2、JAVA中的数据类型有
基本数据类型:
占用空间 取值范围
整数型 byte 1 -128 —— 127
short 2 -32768 —— 32767
int 4 -2147483648 —— 2147483647
long 8 -2^63 —— 2^63-1
浮点型 float 4 ——————
double 8 ——————
布尔型 boolean 1 true/false
字符型 char 2 0 —— 65535
short和char实际上容量相同,不过char可以表示更大的数字。
因为char表示的是文字,文件没有正负之分,所以char可以表示更大的数字。
引用数据类型:
java中除了基本数据类型之外,剩下的都是引用数据类型。
1.3、什么是字符编码
字符编码是人为的定义的一套转换表。
在字符编码中规定了一系列的文字对应的二进制。
字符编码其实本质上就是一本字典,该字段中描述了文字与二进制之间的对照关系。
字符编码是人为规定的。(是某个计算机协会规定的。)
字符编码涉及到编码和解码两个过程,编码和解码的时候必须采用同一套字符编码方式,不然就会出现乱码。
1.4、关于字符编码的发展过程?
起初的时候计算机是不支持文字的,只支持科学计算。实际上计算机起初是为了战争而开发的,计算导弹的轨道....
后来随着计算机的发展,计算机开始支持文字,最先支持的文字是英文,英文对应的字符编码方式是:ASCII码。
ASCII码采用1byte进行存储,因为英文字母是26个。(键盘上所有的键全部算上也超不过256个。1byte可以表示256种不同的情况。所以英文本身在计算机方面就占有优势。)
'a' --(采用ASCII码进行编码)-> 01100001
01100001 --(采用ASCII码进行解码)-> 'a'
如果编码和解码采用的不是同一个编码方式,会出现乱码。
'b' ---> 98
'c' ---> 99...
'a' ---> 97
'A' ---> 65
'B' ---> 66
...
'0' ---> 48 (这个'0'不是那个0,是文字'0')
'1' ---> 49
随着计算机语言的发展,后来国际标准组织制定了ISO-8859-1编码方式,
又称为latin-1编码方式,向上兼容ASCII码。但不支持中文。
后来发展到亚洲,才支持中文,日文,韩文....
中文这块的编码方式:GB2312<GBK<GB18030 (容量的关系)
以上编码方式是简体中文。
繁体中文:big5(台湾使用的是大五码。)
在java中,java语言为了支持全球所有的文字,采用了一种字符编码方式
叫做unicode编码。unicode编码统一了全球所有的文字,支持所有文字。
具体的实现包括:UTF-8 UTF-16 UTF-32....
需要记住:
ASCII('a'是97 'A'是65 '0'是48...)
ISO-8859-1(latin-1)
GB2312
GBK
GB18030
Big5
unicode(utf8 utf16 utf32)
1.1、没有超出char的取值范围可以直接赋值给char变量吗?
当一个整数赋值给char类型变量的时候,会自动转换成char字符型,最终的结果是一个字符。
当一个整数没有超出byte short char的取值范围的时候,这个整数可以直接赋值给byte short char类型的变量。
1.2、综合的看一下,在类型转换的时候需要遵循哪些规则?
第一条:八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以
进行转换;
第二条:如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋
值给byte,short,char 类型的变量;
第三条:小容量向大容量转换称为自动类型转换,容量从小到大的排序为:
byte < short(char) < int < long < float < double,其中 short和 char
都占用两个字节,但是char 可以表示更大的正整数;
第四条:大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,
但运行时可能出现精度损失,谨慎使用;
第五条:byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;
第六条:多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;char+short+byte 这个除外。
所有的面试题都超不出以上的6条规则。死记硬背。
1.3、计算机在底层存储数据的时候,一律存储的是“二进制的补码形式”
1、计算机在任何情况下都只能识别二进制
2、计算机在底层存储数据的时候,一律存储的是“二进制的补码形式”
计算机采用补码形式存储数据的原因是:补码形式效率最高。
3、什么是补码呢?
实际上是这样的,二进制有:原码 反码 补码
4、记住:
对于一个正数来说:二进制原码、反码、补码是同一个,完全相同。
int i = 1;
对应的二进制原码:00000000 00000000 00000000 00000001
对应的二进制反码:00000000 00000000 00000000 00000001
对应的二进制补码:00000000 00000000 00000000 00000001
对于一个负数来说:二进制原码、反码、补码是什么关系呢?
byte i = -1;
对应的二进制原码:10000001
对应的二进制反码(符号位不变,其它位取反):11111110
对应的二进制补码(反码+1):11111111
5、分析 byte b = (byte)150;
这个b是多少?
int类型的4个字节的150的二进制码是什么?
00000000 00000000 00000000 10010110
将以上的int类型强制类型转为1个字节的byte,最终在计算机中的二进制码是:
10010110(这是补码)
千万要注意:计算机永远存储的都是二进制补码形式。也就是说上面10010110 这个是一个二进制补码形式,你可以采用逆推导的方式推算出这个二进制补码对应的原码是啥!!!!!!
10010110 ---> 二进制补码形式
10010101 ---> 二进制反码形式
11101010 ---> 二进制原码形式
eg:
public class IntTest05{
public static void main(String[] args){
// 编译报错:因为150已经超出了byte取值范围,不能直接赋值,需要强转
//byte b = 150;
byte b = (byte)150;
// 这个结果会输出多少呢?
System.out.println(b); // -106
}
}
1.1、怎么接收用户键盘输入?
java.util.Scanner s = new java.util.Scanner(System.in);
// 接收整数
int i = s.nextInt()
// 接收字符串
String str = s.next(); next()方法只能读取空格前的一个段字符串
String str = s.nextLine(); 常用;
next() 与 nextLine() 区别:
next():
1、一定要读取到有效字符后才可以结束输入。
2、对输入有效字符之前遇到的空白,next() 方法会自动将其去掉。
3、只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符。next() 不能得到带有空格的字符串。
nextLine():
1、以Enter为结束符,也就是说 nextLine()方法返回的是输入回车之前的所有字符。
2、可以获得空白。
//接收单个字符
char c =sc.next().charAt(0);
1.2、赋值运算符和比较运算符
基本运算符: =
扩展运算符: += -= *= /= %=
注意:扩展赋值运算符在编写的时候,两个符号之间不能有空格。
很重要的语法机制:
使用扩展赋值运算符的时候,永远都不会改变运算结果类型。
byte x = 100;
x += 1;
x自诞生以来是byte类型,那么x变量的类型永远都是byte。不会变。
不管后面是多大的数字。
比较运算符==和!= :
1. 在java中,不能用“==”和“!=”来判断两个字符串是否相等。因为String是引用类型,而不是基本数据类型。故它们 的比较是使用地址和值来比较,因为它们是不同的对象,有不同的地址。
2. Java中必须使用string1.equals(string2)来进行判断
string s1="Hello";
string s2="Hello";
则(s1==s2)=true;
因为他们指向的同一个对象。
String s1=new String("Hello");
String s2=new String("Hello");
则(s1==s2)=false
如果把其他变量的值赋给s1和s2,即使内容相同,由于不是指向同一个对象,也会返回false。
所以建议使用equals(),因为equals比较的才是真正的内容
1.3、条件运算符:(三目运算符。)
语法格式:
布尔表达式 ? 表达式1 : 表达式2
执行原理是什么?
布尔表达式的结果为true时,表达式1的执行结果作为整个表达式的结果。
布尔表达式的结果为false时,表达式2的执行结果作为整个表达式的结果。
1.4、"+"运算符
1、+ 运算符在java语言中有两个作用。
作用1:求和
作用2:字符串拼接
2、什么时候求和?什么时候进行字符串的拼接呢?
当 + 运算符两边都是数字类型的时候,求和。
当 + 运算符两边的“任意一边”是字符串类型,那么这个+会进行字符串拼接操作。
3、一定要记住:字符串拼接完之后的结果还是一个字符串。
1.5、if语句的语法结构以及运行原理?
if语句是分支语句,也可以叫做条件语句。
if语句的语法格式:
第一种写法:
if(布尔表达式){
java语句;
java语句;
}
这里的一个大括号{} 叫做一个分支。
if 这个单词翻译为如果,所以又叫做条件语句。
该语法的执行原理是:
如果布尔表达式的结果是true,则执行大括
号中的程序,否则大括号中代码不执行。
第二种写法:
if(布尔表达式){ // 分支1
java语句;
}else{ // 分支2
java语句;
}
执行原理:如果布尔表达式的结果是true,则执行
分支1,分支2不执行。如果布尔表达式的结果是false,
分支1不执行,执行分支2.
以上的这个语句可以保证一定会有一个分支执行。
else表示其它。
第三种写法:
if(布尔表达式1){ // 分支1
java语句;
}else if(布尔表达式2){ // 分支2
java语句;
}else if(布尔表达式3){
java语句;
}else if(布尔表达式4){
java语句;
}....
以上if语句的执行原理?
先判断“布尔表达式1”,如果“布尔表达式1”为true,则执行分支1,
然后if语句结束了。
当“布尔表达式1”结果是false,那么会继续判断布尔表达式2的结果,
如果布尔表达式2的结果是true,则执行分支2,然后整个if就结束了。
从上往下依次判断,主要看第一个true发生在哪个分支上。
第一个true对应的分支执行,只要一个分支执行,整个if结束。
第四种写法:
if(布尔表达式1){ // 分支1
java语句;
}else if(布尔表达式2){ // 分支2
java语句;
}else if(布尔表达式3){
java语句;
}else if(布尔表达式4){
java语句;
}else{
java语句; // 以上条件没有一个成立的。这个else就执行了。
}
注意:
1、对于if语句来说,在任何情况下只能有1个分支执行,不可能
存在2个或者更多个分支执行。if语句中只要有1个分支执行了,
整个if语句就结束了。(对于1个完整的if语句来说的。)
2、以上4种语法机制中,凡是带有else分支的,一定可以保证会有
一个分支执行。
3、当分支当中“java语句;”只有1条,那么大括号{}可以省略,但为了
可读性,最好不要省略。(有的程序员在编写代码的时候,可能会故意
将大括号{}省略,你能看懂就行。)
4、控制语句和控制语句之间是可以嵌套的,但是嵌套的时候大家最好
一个语句一个语句进行分析,不要冗杂在一起分析。
1.6、switch语句
switch语句的语法格式
switch(值){
case 值1:
java语句;
java语句;...
break;
case 值2:
java语句;
java语句;...
break;
case 值3:
java语句;
java语句;...
break;
default:
java语句;
}
以上是一个完整的switch语句:
其中:break;语句不是必须的。default分支也不是必须的。
如果分支执行了,但是分支最后没有“break;”,此时会发生case穿透现象。
switch语句支持的值有哪些?
支持int类型以及String类型。
但一定要注意JDK的版本,JDK8之前不支持String类型,只支持int。
在JDK8之后,switch语句开始支持字符串String类型。
switch语句本质上是只支持int和String,但是byte,short,char也可以
使用在switch语句当中,因为byte short char可以进行自动类型转换。
switch语句中“值”与“值1”、“值2”比较的时候会使用“==”进行比较。
Switch 注意事项:
如果没有break语句,那么会顺序执行语句直到碰到breaak;
即:
switch语句结束的条件:碰到了break或者右大括号
eg:
public class Test42_45 {
public static void main(String[] args) {
int a = 1;
int x = 0;
int y = 0;
switch(a) {
case 0:
y++;//因为case不为0,所以跳过y++
case 1:
x++;
case 2:
x++;
y++;
}
System.out.println(x+" "+y);
}
}
//结果是2.1
1.7、for循环的语法机制?
语法机制:
for(初始化表达式; 条件表达式; 更新表达式){
循环体; // 循环体由java语句构成
java语句;
java语句;
java语句;
java语句;
....
}
注意:
第一:初始化表达式最先执行,并且在整个循环中只执行一次。
第二:条件表达式结果必须是一个布尔类型,也就是:true或false
1.8、while循环的语法机制
语法机制:
while(布尔表达式){
循环体;
}
while循环有没有可能循环次数为0次?
可能。
while循环的循环次数是:0~n次
1.9、do…while循环语句的语法机制:
语法机制:
do {
循环体;
}while(布尔表达式);
注意:do..while循环最后的时候别漏掉“分号”
对于do..while循环来说,循环体至少执行1次。循环体的执行次数是:1~n次。
2.0、continue;语句
1、continue翻译为:继续
2、continue语句和break语句要对比着学习
3、continue语句的作用是:
终止当前"本次"循环,直接进入下一次循环继续执行。
for(){
if(){ // 当这个条件成立时,执行continue语句
continue; //当这个continue语句执行时,continue下面的代码不执行,直接进入下一次循环执行。
}
// 以上的continue一旦执行,以下代码不执行,直接执行更新表达式。
code1;
code2;
code3;
code4;
}
2.1、break;
默认情况下,终止离它最近的循环。
当然,也可以通过标识符的方式,终止指定的循环。
回顾
2.1、windows操作系统中,文件扩展名的展示。
2.3、windows的dos命令
cls 清屏
exit 退出
ipconfig 查看IP地址
ping 查看两台计算机之间是否可以正常通信
d:+回车 切换盘符
cd 命令切换目录:相对路径和绝对路径
C:\Windows>cd System32 相对路径(相对于当前位置而言)
C:\>cd c:\windows\system32 绝对路径(路径以盘符开始)
cd .. 回到上级
cd \ 回到根
mkdir 创建目录
del 删除文件
dir 查看当前目录下有哪些子目录或者子文件
注意:
在DOS命令窗口中,可以使用tab键自动补全。
在DOS命令窗口中,使用上下箭头可以翻出历史命令。
2.6、Java语言的发展史
JDK:java开发工具包
JavaSE JavaEE JavaME
SUN公司开发的,带头人:james gosling java之父
2.7、java语言的特点:
简单性
多线程
面向对象
可移植,跨平台:因为JVM的存在。(Java虚拟机屏蔽了操作系统之间的差异)
健壮性:自动GC垃圾回收机制。
2.8、java的加载与执行(java从开发到最终运行,经历了哪些过程)
要求:自己能够从头描述到最后。(不参考任何资料的前提下)
从编写到最终的运行,把过程描述出来。
第一步:
第二步:
.....
2.9、术语
JDK java开发工具包
JRE java运行时环境
JVM java虚拟机
JavaSE JavaEE JavaME
2.10、开始开发第一个java程序HelloWorld
第一:要会下载对应版本的JDK(http://www.oracle.com)
第二:要会安装JDK(双击,下一步)
第三:配置环境变量path
path=C:\Program Files\Java\jdk-13.0.2\bin
这样javac和java命令就可以使用了。
第四:编写HelloWorld.java程序。
第五:javac进行编译:
javac命令在使用的时候
javac + java源文件的路径(注意:路径包括绝对和相对。)
第六:java命令进行运行
java 类名 (一定要注意:这里不是路径。是类名)
这里涉及到另一个环境变量叫做:classpath
classpath没有配置的情况下:从当前路径下找xxx.class文件
classpath设置了具体路径之后,不再从当前路径下找了。
重点掌握path和classpath两个环境变量。
2.11、java语言中的注释:
// 单行注释
/*
多行注释
*/
/**
* javadoc注释
*/
2.12、public class 和 class的区别:
一个java文件中可以定义多个class
一个class编译之后会生成1个class字节码文件,2个class编译之后会生成2个class文件
任何一个class中都可以编写main方法,每一个main方法都是一个入口
public的类可以没有
public的类如果有的话,只能有1个,并且public的类名要求和文件名一致。
class A{
main(){}
}
java A
class B{
main(){}
}
java B
....
2.13、标识符
标识符可以标识什么?
类名、接口名
变量名、方法名
常量名
标识符的命名规则?
标识符只能由数字 字母(可以有中文) 下划线 美元符号组成,不能有其它符号。
标识符不能以数字开始
标识符严格区分大小写
关键字不能做标识符
理论上没有长度限制
标识符的命名规范?
见名知意
驼峰命名方式,一高一低
类名、接口名:首字母大写,后面每个单词首字母大写。
变量名、方法名:首字母小写,后面每个单词首字母大写。
常量名:全部大写,每个单词之间使用下划线衔接。
2.14、关键字
关键字都是全部小写的,在editplus中以蓝色显示。
不需要特意记忆,一边学习一边记忆。
public
class
break
continue
........
2.15、变量
什么是变量,怎么理解的?
一个存储数据的盒子,一个存储数据的单元。
int i = 100;
System.out.println(i);
什么是字面量,怎么理解的?
1 2 3 4 -100 100 整数型字面量
3.14 浮点型的字面量。
true false 布尔型字面量
'a' '中' 字符型字面量
"abc" "a" 字符串型的字面量
字面量其实本质上就是“数据”。
变量怎么声明,怎么赋值?
声明:数据类型 变量名;
赋值:变量名 = 字面量;
变量在同一个作用域当中不能重名。
变量的分类?
在方法体当中声明的就是局部变量。
在方法体外面声明的就是成员变量。
成员变量如果没有被static修饰就是实例变量,否则静态变量。
变量的作用域?
出了大括号就不认识了。
2.16、数据类型
1. 什么是数据类型,有啥用?
数据类型决定了变量分配空间(在内存中分配空间)的大小,类型不同,空间大小不同。
计算机的主要部件:CPU 内存 硬盘 主板。
2、数据类型分类?
基本数据类型:
byte short int long float double boolean char
引用数据类型:
除基本数据类型外都是。
3、要求要理解二进制
4、要求理解二进制和十进制之间的互相转换。
5、8种基本数据类型,每个占用空间大小。
类型 字节
------------------
byte 1
short 2
int 4
long 8
float 4
double 8
boolean 1
char 2
6、记忆byte short int char的取值范围:
byte -128 ~ 127
short -32768 ~ 32767
int -2147483648 ~ 2147483647
char 0~65535
7、理解字符编码?
什么时候会有乱码?编码和解码采用的不是同一套字符编码方式。
怎么理解字符编码?字符编码是人为制定的,一个字典表,字典中描述了转换关系。
常见的字符编码?
ASCII:
'a' 97
'A' 65
'0' 48
...
ISO-8859-1(latin-1)
GB2312
GBK
GB18030
Big5
unicode : java中采用的统一了全球所有的文字。
8、数据类型详细介绍
char
可以存储1个汉字
用单引号括起来
转义字符:
\t
\n
\'
\"
\\
\u十六进制数
....
char c = 97;
System.out.println(c); //输出'a'
byte short int long
int最常用
任何一个数字,例如:1232 3 5 9,默认都是当做int处理,想当做long,必须加L或者l
123L这就是long类型
自动类型转换:小-->大
强制类型转换:大-->小,需要加强制类型转换符。另外运行可能损失精度。
当一个整数没有超出byte short char的取值范围,可以直接赋值给byte short char类型的变量。
在java中整数型字面量表示的时候有四种方式:
10 十进制
010 八进制
0x10 十六进制
0b10 二进制
float double
浮点型的数字默认被当做double来处理,想以float形式存在,数字后面添加F/f
float f = 1.0; //错误的
float f = 1.0f;
float f = (float)1.0;
要知道浮点型数据在java语言中存储的都是近似值。
还有一点:float和double的空间永远比整数型空间大,比long大。
boolean
boolean类型只有两个值:true false,没有其他值。
9、基本数据类型转换的6条规则:
第一条:只有boolean不能转换,其它都行。
第二条:自动类型转换
byte < short(char) < int < long < float < double
char可以取到更大的正整数。
第三条:强制类型转换需要加强制类型转换符。可能损失精度。
第四条:当一个整数没有超出byte short char的取值范围时,可以直接赋值
给byte short char类型的变量。
第五条:byte short char混合运算的时候,各自先转换成int再做运算。
第六条:多种数据类型混合运算的时候,先转换成容量最大的那一种再做运算,除第五条。
2.17、运算符
算术运算符
+ - * / % ++ --
重点:++
++无论出现在变量前还是后,只要++运算结束,一定会自加1.
int i = 10;
i++;
System.out.println(i); // 11
int k = 10;
++k;
System.out.println(k); // 11
++出现在变量前:
int i = 10;
int k = ++i;
System.out.println(k); // 11
System.out.println(i); // 11
++出现在变量后:
int i = 10;
int k = i++;
System.out.println(k); // 10
System.out.println(i); // 11
int i = 10;
System.out.println(i++); // 10
解开以上题目的窍门是什么?拆代码
int temp = i++;
System.out.println(temp); // 10
System.out.println(i); // 11
int i = 10;
System.out.println(++i);
会拆代码:
int temp = ++i;
System.out.println(temp); // 11
System.out.println(i); // 11
关系运算符
>、>=、<、<=、==、!=
结果都是布尔类型。true/false
逻辑运算符
&、|、!、&&、||
逻辑运算符要求两边都是布尔类型,并且最终结果还是布尔类型。
左边是布尔类型 & 右边还是布尔类型 -->最终结果还是布尔类型。
& 两边都是true,结果才是true、| 一边是true,结果就是true、! 取反
&&实际上和&运算结果完全相同,区别在于:&&有短路现象。左边的为false的时候:&& 短路了。
左边为true的时候:|| 短路。
赋值运算符
=、+=、-=、*=、/=、%=
重要规则:
扩展赋值运算符在使用的时候要注意,不管怎么运算,最终的
运算结果类型不会变。
byte x = 100; // byte最大值127
x += 1000; // 编译可以通过,x变量还是byte类型,只不过损失精度了。
x += 1000; 等同于: x = (byte)(x + 1000);
int i = 10;
i += 10; // 等同于:i = i + 10; 累加。
三目运算符
布尔表达式 ? 表达式1:表达式2
字符串连接运算符
+
+ 两边都是数字,进行求和。
+ 有一边是字符串,进行字符串的拼接。
+ 有多个的话,遵循自左向右依次执行:1 + 2 + 3
如果想让其中某个加号先执行,可以添加小括号:1 + (2 + 3)
注意:字符串拼接完之后的结果还是一个字符串。
技巧:怎么把一个变量塞到一个字符串当中。
String name = "jackson";
System.out.println("登录成功,欢迎"+name+"回来");
2.18、控制语句
选择语句
if
switch
循环语句
for
while
do..while
转向语句
break;
continue;
return;
1、选择语句/分支语句 if
四种写法。
语法机制:
if(布尔表达式){
}
if(布尔表达式){
}else{
}
if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}
if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}else if(布尔表达式){
}else{
}
if语句嵌套:
if(布尔表达式){ //前提条件
if(布尔表达式){
if(布尔表达式){
}else{
}
}
}else{
}
执行原理:
对于一个if语句来说,只要有1个分支执行,整个if语句结束。
当布尔表达式的结果为true时,分支才会执行。
分支当中只有一条java语句,大括号可以省略。
带有else的可以保证肯定会有一个分支执行。
2、选择语句/分支语句 switch
完整语法结构:
switch(值){ //值允许是String、int,(byte,short,char可以自动转换int)
case 值1: case 值x:
java语句;
break;
case 值2:
java语句;
break;
case 值3:
java语句;
break;
default:
java语句;
}
3、for循环
for循环语法机制:
for(初始化表达式;条件表达式;更新表达式){
循环体;
}
for(int i = 0; i < 10; i++){
System.out.println(i);
}
for循环执行原理:
1、先执行初始化表达式,并且只执行1次。
2、然后判断条件表达式
3、如果为true,则执行循环体。
4、循环体结束之后,执行更新表达式。
5、继续判断条件,如果条件还是true,继续循环。
6、直到条件为false,循环结束。
4、while循环
while(布尔表达式){
循环体;
}
执行次数:0~N次。
5、do..while循环
do{
循环体;
}while(布尔表达式);
执行次数:1~N次。
6、break;
默认情况下,终止离它最近的循环。
当然,也可以通过标识符的方式,终止指定的循环。
for(int i = 0; i < 10; i++){
if(i == 5){
break;
}
code1;
code2;
code3;
code4;
....
}
7、continue;
终止当前“本次”循环,直接跳入下一次循环继续执行。
for(int i = 0; i < 10; i++){
if(i == 5){
continue;
}
code1;
code2;
code3;
code4;
....
}
1.1、什么是方法
方法是一段可以完成某个特定功能的并且可以被重复利用的代码片段。
方法的出现,让代码具有了很强的复用性。
1.2、方法
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
注意:
以上中括号[]里面的内容表示不是必须的,是可选的。
方法体由Java语句构成。
方法定义之后需要去调用,不调用是不会执行的。
当一个方法执行结束不返回任何值的时候,返回值类型也不能空白,必须写上void关键字。所以void表示该方法执行结束后不返回任何结果。
如果返回值类型“不是void”,那么你在方法体执行结束的时候必须使用"return 值;"这样的语句来完成“值”的返回,如果没有“return 值;”这样的语句那么编译器会报错。
只要有“return”关键字的语句执行,当前方法必然结束。return只要执行,当前所在的方法结束,记住:不是整个程序结束。
如果返回值类型是void,那么在方法体当中不能有“return 值;”这样的语句。但是可以有“return;”语句。“return;”的作用就是用来终止当前方法的。
方法名要见名知意。(驼峰命名方式)
方法名在标识符命名规范当中,要求首字母小写,后面每个单词首字母大写。
只要是合法的标识符就行。
怎么调用,语法是什么?
类名.方法名(实际参数列表); 实参和形参的类型必须一一对应,另外个数也要一一对应。
a()方法调用b()方法的时候,a和b方法都在同一个类中,“类名.”可以省略。如果不在同一个类中“类名.”不能省略。
break;语句和return;语句有什么区别?
不是一个级别。
break;用来终止switch和离它最近的循环。
return;用来终止离它最近的一个方法。
1.3、数组
数组的定义
元素的数据类型[] 数组名称 = new 元素的数据类型[数组容器的大小]
分类:
动态初始化:在程序运行的过程中,才能知道究竟给元素赋什么样的值
元素的数据类型[] 数组名称 = new 元素的数据类型[数组容器的大小]
索引:
元素在数组中的位置数字,别名:下标,角标。从0开始到数组的长度-1结束。
注意:
1、所有的元素都要赋值,如果没有赋值,会根据数据类型进行默认的赋值整数类型就是0,小数类型是0.0
2、访问的索引的下标最大只能到数组容器的大小-1,否则会报错
静态初始化:在程序书写的时候,就知道数组中赋了什么样的值
元素的数据类型[] 数组名称 = new 元素的数据类型[]{写上各种元素值的罗列};
或者: 元素的数据类型[] 数组名称 = {元素值的罗列};
注意:
1、不能在第二个中括号中写元素的个数
2、元素值的罗列,使用逗号进行分隔,还要保证元素值都是同一个类型
3、静态初始化使用简写格式的时候,对于数组名称的赋值,不能分为两行写的。
数组索引越界异常:
java.lang.ArrayIndexOutOfBoundsException:
原因:访问了数组中,不存在的索引。数组索引的范围是在0 -—————— 长度-1,访问了超过这个范围的索引,就会 出现数组索引越界异常。
空指针异常:
原因:当引用不再指向任何对内存中的数据时,仍然要通过这个引用访问堆内存中的数据,肯定就会抛出异常
避免:将来在访问堆内存中的数据之前,先判断引用是否为null,如果是就不让它访问了,不是才可以访问。
数组的长度:
数组的名称.length;
索引:
表示元素在数组中的位置
范围:0 - (数组的长度-1结束)
数组的访问:
数组名称[索引];
1.1、方法重载机制
使用方法重载机制。解决之前的两个缺点。
优点1:代码整齐美观。
优点2:“功能相似”的,可以让“方法名相同”,更易于以后的代码编写。
什么时候需要考虑使用方法重载?
在同一个类当中,如果“功能1”和“功能2”它们的功能是相似的,
那么可以考虑将它们的方法名一致,这样代码既美观,又便于
后期的代码编写(容易记忆,方便使用)。
代码满足什么条件的时候构成了方法重载?
条件1:在同一个类当中
条件2:方法名相同
条件3:形式参数列表不同(类型、个数、顺序)
注意:
方法重载和返回值类型无关,和修饰符列表无关。
1.2、方法递归
1、什么是方法递归?
方法自己调用自己,这就是方法递归。
2、当递归时程序没有结束条件,一定会发生:
栈内存溢出错误:StackOverflowError
原因:一直压栈,没有弹栈,栈内存不够用。
所以:递归必须要有结束条件。(这是一个非常重要的知识点。)
JVM发生错误之后只有一个结果,就是退出JVM。
3、递归假设是有结束条件的,就一定不会发生栈内存溢出错误吗?
假设这个结束条件是对的,是合法的,递归有的时候也会出现栈内存溢出错误。
因为有可能递归的太深,栈内存不够了。因为一直在压栈。
4、在实际的开发中,不建议轻易的选择递归,能用for循环while循环代替的,尽量
使用循环来做。因为循环的效率高,耗费的内存少。递归耗费的内存比较大,另外递归的使用不当会导致JVM死掉。
(但在极少数的情况下,不用递归,这个程序没法实现。)
所以:递归我们还是要认真学习的。
5、在实际的开发中,假设有一天你真正的遇到了:StackOverflowError
你怎么解决这个问题,可以谈一下你的思路吗?
我来谈一下我的个人思路:
首先第一步:
先检查递归的结束条件对不对。如果递归结束条件不对,
必须对条件进一步修改,直到正确为止。
第二步:假设递归条件没问题,怎么办?
这个时候需要手动的调整JVM的栈内存初始化大小。
可以将栈内存的空间调大点。(可以调整大一些。)
第三步:调整了大小,如果运行时还是出现这个错误,
没办法,只能继续扩大栈的内存大小。
(java -X)这个可以查看调整堆栈大小的参数
1.1、面向过程和面向对象有什么区别?
从语言方面出发:
对于C语言来说,是完全面向过程的。
对于C++语言来说,是一半面向过程,一半是面向对象。(C++是半面向对象的)
对于Java语言来说,是完全面向对象的。
什么是面向过程的开发方式?
面向过程的开发方式主要的特点是:
注重步骤,注重的是实现这个功能的步骤。
第一步干什么
第二步干什么
....
另外面向过程也注重实现功能的因果关系。
因为A所有B
因为B所以C
因为C所以D
.....
面向过程中没有对象的概念。只是实现这个功能的步骤以及因果关系。
面向过程有什么缺点?(耦合度高,扩展力差。)
面向过程最主要是每一步与每一步的因果关系,其中A步骤因果关系到B
步骤,A和B联合起来形成一个子模块,子模块和子模块之间又因为因果
关系结合在一起,假设其中任何一个因果关系出现问题(错误),此时
整个系统的运转都会出现问题。(代码和代码之间的耦合度太高,扩展力
太差。)
面向过程有什么优点?(快速开发)
对于小型项目(功能),采用面向过程的方式进行开发,效率较高。
不需要前期进行对象的提取,模型的建立,采用面向过程
方式可以直接开始干活。一上来直接写代码,编写因果关系。
从而实现功能。
什么是面向对象的开发方式?
采用面向对象的方式进行开发,更符合人类的思维方式。(面向对象成为主流的原因)
人类就是以“对象”的方式去认识世界的。
所以面向对象更容易让我们接受。
面向对象就是将现实世界分割成不同的单元,然后每一个单元
都实现成对象,然后给一个环境驱动一下,让各个对象之间协
作起来形成一个系统。
1.2、当我们采用面向对象的方式贯穿整个系统的话,涉及到三个术语:
OOA:面向对象分析(Object-Oriented-Analysis)
OOD:面向对象设计(Object-Oriented-Design)
OOP:面向对象编程(Object-Oriented-Programming)
整个软件开发的过程,都是采用OOA进行贯穿的。
实现一个软件的过程:
分析(A) --> 设计(D) --> 编程(P)
面向对象包括三大特征
封装\继承\多态
1.3、类和对象的概念
什么是类?
类实际上在现实世界当中是不存在的,是一个抽象的概念。
是一个模板。是我们人类大脑进行“思考、总结、抽象”的一个结果。
类本质上是现实世界当中某些事物具有的共同特征,将这些共同
特征提取出来形成的概念就是一个“类”,“类”就是一个模板。
什么是对象?
对象是实际存在的个体。(真实存在的个体)
eg:
宋小宝就是一个对象
姚明就是一个对象
刘德华就是一个对象
在java语言中,要想得到“对象”,必须先定义“类”,“对象”是通过“类”这个模板创造出来的。类就是一个模板:类中描述的是所有对象的“共同特征信息” 对象就是通过类创建出的个体。
这几个术语你需要自己能够阐述出来:
类:不存在的,人类大脑思考总结一个模板(这个模板当中描述了共同特征。)
对象:实际存在的个体。
实例:对象还有另一个名字叫做实例。
实例化:通过类这个模板创建对象的过程,叫做:实例化。
抽象:多个对象具有共同特征,进行思考总结抽取共同特征的过程。
类 --【实例化】--> 对象(实例)
对象 --【抽象】--> 类
类 = 属性 + 方法
属性来源于:状态
方法来源于:动作
1.4、类的定义
怎么定义一个类,语法格式是什么?
[修饰符列表] class 类名 {
//类体 = 属性 + 方法
// 属性在代码上以“变量”的形式存在(描述状态)
// 方法描述动作/行为
}
注意:修饰符列表可以省略。
为什么属性是以“变量”的形式存在的?
答案:是因为属性对应的是“数据”,数据在程序中只能放到变量中。
结论:属性其实就是变量。
1.5、对象在语法级别上是怎么完成对象创建的呢?
类名 变量名 = new 类名();
这样就完成了对象的创建。
对象又被称为实例。
实例变量实际上就是:对象级别的变量。
实例相关的有:实例变量、实例方法。
方法没有static,这样的方法被称为:实例方法。(对象方法,对象级别的方法)
实例相关的都需要先new对象,通过“引用.”的方式去访问。
实例变量都存储在哪里?
实例变量都在堆内存的对象内部。
1.6、对象和引用的区别?
对象:是通过new出来的,在堆内存中存储。
引用:但凡是变量,并且该变量中保存了内存地址指向了堆内存当中的对象的。
1.7、空指针异常。(NullPointerException)
出现空指针异常的前提条件是?
"空引用"访问实例【对象相关】相关的数据时,都会出现空指针异常。
关于垃圾回收器:GC
在java语言中,垃圾回收器主要针对的是堆内存。
当一个java对象没有任何引用指向该对象的时候,GC会考虑将该垃圾数据释放回收掉。
1.8、方法调用时参数传递
java中规定:参数传递的时候,和类型无关,不管是基本数据类型还是引用数据类型
统一都是将盒子中保存的那个“值”复制一份,传递下去。内存地址也是值,也是盒子中保存的一个东西。
1.1、构造方法
什么是构造方法,有什么用?
构造方法是一个比较特殊的方法,通过构造方法可以完成对象的创建,
以及实例变量的初始化。换句话说:构造方法是用来创建对象,并且
同时给对象的属性赋值。(注意:实例变量没有手动赋值的时候,系统
会赋默认值。)
构造方法作用:
创建对象,并且创建对象的过程中给属性赋值(初始化。)
重点(需要记忆):当一个类没有提供任何构造方法,系统会默认提供一个无参数的构造方法。
(而这个构造方法被称为缺省构造器。)
当一个类中手动的提供了构造方法,那么系统将不再默认提供无参数构造方法。
建议将无参数构造方法手动的写出来,这样一定不会出问题。
对于实例变量来说,只要你在构造方法中没有手动给它赋值,统一都会默认赋值。默认赋系统值。
调用构造方法怎么调用呢?使用哪个运算符呢?
使用new运算符来调用构造方法。语法格式:
new 构造方法名(实际参数列表);
构造方法的语法结构是?
[修饰符列表] 构造方法名(形式参数列表){
构造方法体;
通常在构造方法体当中给属性赋值,完成属性的初始化。
}
注意:
第一:修饰符列表目前统一写:public。千万不要写public static。
第二:构造方法名和类名必须一致。
第三:构造方法不需要指定返回值类型,也不能写void,写上void
表示普通方法,就不是构造方法了。
普通方法的语法结构是?
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}
思考:实例变量没有手动赋值的时候,实际上系统会默认赋值,
那么这个默认赋值操作是在什么时间进行的?是在类加载的时候给这些实例变量赋值吗?
不是,实例变量是在构造方法执行的过程中完成初始化的,完成赋值的。
1.2、构造方法支持方法重载吗?
构造方法是支持方法重载的。
在一个类当中构造方法可以有多个。
并且所有的构造方法名字都是一样的。
方法重载特点:
在同一个类中,方法名相同,参数列表不同。
1.3、构造方法主要知识点
1.构造方法有什么作用?
2.构造方法怎么定义,语法是什么?
3.构造方法怎么调用,使用哪个运算符?
4.什么是缺省构造器?
5.怎么防止缺省构造器丢失?
6.实例变量在什么时候初始化?
1.1、面向对象的首要特征:封装 。什么是封装?有什么用?
有了封装,才有继承,有了继承,才能说多态。
封装的作用有两个:
第一个作用:保证内部结构的安全。
第二个作用:屏蔽复杂,暴露简单。
在代码级别上,封装有什么用?
一个类体当中的数据,假设封装之后,对于代码的调用人员来说,
不需要关心代码的复杂实现,只需要通过一个简单的入口就可以访问了。
另外,类体中安全级别较高的数据封装起来,外部人员不能随意访问,
来保证数据的安全性。
1.2、怎么进行封装,代码怎么实现?
第一步:属性私有化(使用private关键字进行修饰。)
第二步:1个属性对外提供两个set和get方法。外部程序只能通过set方法修改,只能通过get方法读取,可以在set方法中设 立关卡来保证数据的安全性。
get和set方法应该带有static,还是不应该有static,get和set方法应该定义为实例方法吗?
set和get方法都是实例方法,不能带static。不带static的方法称为实例方法,实例方法的调用必须先new对象。 get读年龄,set改年龄,这个读和改都是操作的一个对象的年龄。(没有对象何来年龄)
封装的第二步:对外提供公开的set方法和get方法作为操作入口。并且都不带static。都是实例方法。
[修饰符列表] 返回值类型 方法名(形式参数列表){}
注意:
java开发规范中有要求,set方法和get方法要满足以下格式。
get方法的要求:
public 返回值类型 get+属性名首字母大写(无参){
return xxx;
}
set方法的要求:
public void set+属性名首字母大写(有1个参数){
xxx = 参数;
}
1.3、static关键字
1、static翻译为“静态”
2、所有static关键字修饰的都是类相关的,类级别的。
3、所有static修饰的,都是采用“类名.”的方式访问。
4、static修饰的变量:静态变量
static修饰的静态变量不能定义在方法中。
5、static修饰的方法:静态方法
1.4、变量的分类
变量根据声明的位置进行划分:
在方法体当中声明的变量叫做:局部变量。
在方法体外声明的变量叫做:成员变量。
成员变量又可以分为:
实例变量、静态变量
静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了。
静态变量存储在方法区。
1.5、什么时候变量声明为实例的,什么时候声明为静态的?
如果这个类型的所有对象的某个属性值都是一样的,不建议定义为实例变量,浪费内存空间。建议定义为类级别特征,定义为静态变量,在方法区中只保留一份,节省内存开销。
一个对象一份的是实例变量。
所有对象一份的是静态变量。
实例的:一定需要使用“引用.”来访问。
静态的:建议使用“类名.”来访问,但使用“引用.”也行(不建议使用"引用.")。静态的如果使用“引用.”来访问会让程序员产 生困惑:程序员以为是实例的呢。
1.6、关于方法来说,什么时候定义为实例方法?什么时候定义为静态方法?
如果此方法一般都是描述了一个行为,如果说该行为必须由对象去触发。那么该方法定义为实例方法。
参考标准:
当这个方法体当中,直接访问了实例变量,这个方法一定是实例方法。
我们以后开发中,大部分情况下,如果是工具类的话,工具类当中的方法
一般都是静态的。(静态方法有一个优点,是不需要new对象,直接采用类名
调用,极其方便。工具类就是为了方便,所以工具类中的方法一般都是static的。)
类 = 属性 + 方法
属性描述的是:状态
方法描述的是:行为动作
一个方法代表了一个动作。
1.7、实例相关与静态相关
// 实例相关的都是需要new对象的,通过"引用."访问。
实例变量;
实例方法;
// 静态相关的都是采用“类名.”访问。也可以使用“引用.”,只不过不建议。
静态变量;
静态方法;
1.8、使用static关键字可以定义:静态代码块
什么是静态代码块,语法是什么?
static {
java语句;
java语句;
}
static静态代码块在什么时候执行呢?
类加载时执行。并且只执行一次。静态代码块有这样的特征/特点。
注意:静态代码块在类加载时执行,并且在main方法执行之前执行。静态代码块一般是按照自上而下的顺序执行。
1.9、静态代码块有啥作用,有什么用?
第一:静态代码块不是那么常用。(不是每一个类当中都要写的东西。)
第二:静态代码块这种语法机制实际上是SUN公司给我们java程序员的一个特殊的时刻/时机。这个时机叫做:类加载时机。
具体的业务:
项目经理说了:大家注意了,所有我们编写的程序中,只要是类加载了,请记录一下
类加载的日志信息(在哪年哪月哪日几时几分几秒,哪个类加载到JVM当中了)。
思考:这些记录日志的代码写到哪里呢?
写到静态代码块当中。
栈:方法只要执行,会压栈。(局部变量)
堆:new出来的对象都在堆中。垃圾回收器主要针对。(实例变量)
方法区:类的信息,字节码信息,代码片段。(静态变量)
方法的代码片段放在方法区,但是方法执行过程当中需要的内存在栈中。
// 静态变量在什么时候初始化?类加载时初始化。
// 静态变量存储在哪里?方法区
// 静态代码块什么时候执行?类加载时执行。
2.0、到目前为止,你遇到的所有java程序,有顺序要求的是哪些?
第一:对于一个方法来说,方法体中的代码是有顺序的,遵循自上而下的顺序执行。
第二:静态代码块1和静态代码块2是有先后顺序的。
第三:静态代码块和静态变量是有先后顺序的。
2.1、实例语句块(构造代码块)
实例语句语法?
{
java语句;
java语句;
java语句;
}
实例语句块在什么时候执行?
只要是构造方法执行,必然在构造方法执行之前,自动执行“实例语句块”中的代码。
实际上这也是SUN公司为java程序员准备一个特殊的时机,叫做对象构建时机。
2.2、到目前为止一个类当中可以出现的:
类体{
实例变量;
实例方法;
静态变量;
静态方法;
构造方法;
静态代码块;
实例语句块;
方法(){
// 局部变量
int i = 100;
}
}
// 类加载机制中,是这样的:在程序执行之前,凡是需要加载的类全部加载到JVM当中。
// 先完成加载才会执行main方法。
1.1、this
1.1、this是一个关键字,是一个引用,保存内存地址指向自身。
1.2、this可以使用在实例方法中,也可以使用在构造方法中。
格式:this(实际参数列表);
通过一个构造方法1去调用构造方法2,可以做到代码复用。
但需要注意的是:“构造方法1”和“构造方法2” 都是在同一个类当中。
1.3、this出现在实例方法中其实代表的是当前对象。
1.4、this不能使用在静态方法中,因为this代表当前对象,静态方法中不存在当前对象。。
1.5、this. 大部分情况下可以省略,但是用来区分局部变量和实例变量的时候不能省略。
1.6、this() 这种语法只能出现在构造方法第一行,表示当前构造方法调用本类其他的
构造方法,目的是代码复用。
只要负责调用的方法a和被调用的方法b在同一个类当中:
this. 可以省略
类名. 可以省略
1.1.1、super
super是一个关键字,全部小写。
super能出现在实例方法和构造方法中。
super的语法是:“super.”、“super()”
super不能使用在静态方法中。
super. 大部分情况下是可以省略的。
super.什么时候不能省略呢? ???????
答案是:父中有,子中又有,如果想在子中访问“父的特征”,super. 不能省略。
super() 只能出现在构造方法第一行,通过当前的构造方法去调用“父类”中
的构造方法,目的是:创建子类对象的时候,先初始化父类型特征。
super关键字代表什么呀?
super关键字代表的就是“当前对象”的那部分父类型特征。
super()
表示通过子类的构造方法调用父类的构造方法。
模拟现实世界中的这种场景:要想有儿子,需要先有父亲。
思考:“super(实参)”到底是干啥的?
super(实参)的作用是:初始化当前对象的父类型特征。
并不是创建新对象。实际上对象只创建了1个。
重要的结论:
当一个构造方法第一行:
既没有this()又没有super()的话,默认会有一个super();
表示通过当前子类的构造方法调用父类的无参数构造方法。
所以必须保证父类的无参数构造方法是存在的。
注意:
this()和super() 不能共存,它们都是只能出现在构造方法第一行。
无论是怎样折腾,父类的构造方法是一定会执行的。(百分百的。)
大家要注意:
以后写代码的时候,一个类的无参数构造方法还是建议大家手动的写出来。
如果无参数构造方法丢失的话,可能会影响到“子类对象的构建”。
super.属性名 【访问父类的属性】
super.方法名(实参) 【访问父类的方法】
super(实参) 【调用父类的构造方法】
1.2、extends
什么是继承,有什么用?
继承:在现实世界当中也是存在的,例如:父亲很有钱,儿子不用努力也很有钱。
继承的作用:
基本作用:子类继承父类,代码可以得到复用。(这个不是重要的作用,是基本作用。)
主要(重要)作用:因为有了继承关系,才有了后期的方法覆盖和多态机制。
1.3、继承的相关特性:
① B类继承A类,则称A类为超类(superclass)、父类、基类,
B类则称为子类(subclass)、派生类、扩展类。
class A{}
class B extends A{}
我们平时聊天说的比较多的是:父类和子类。
superclass 父类
subclass 子类
② java 中的继承只支持单继承,不支持多继承,C++中支持多继承,这也是 java 体现简单性的一点
③ 虽然 java 中不支持多继承,但有的时候会产生间接继承的效果,
例如:class C extends B,class B extends A,也就是说,C 直接继承 B,其实 C 还间接继承 A。
④ java 中规定,子类继承父类,除构造方法不能继承之外,剩下都可以继承。
但是私有的属性无法在子类中直接访问。(父类中private修饰的不能在子类中直接访问。可以通过间接的手段来访问。)
⑤ java 中的类没有显示的继承任何类,则默认继承 Object类,Object类是java 语言提供的根类(老祖宗类)
也就是说,一个对象与生俱来就有Object类型中所有的特征。
⑥ 继承也存在一些缺点,例如:CreditAccount 类继承 Account 类会导致它们之间的耦合度非常高
Account 类发生改变之后会马上影响到 CreditAccount 类
1.1、在实际开发中,满足什么条件的时候,我可以使用继承呢?
凡是采用“is a”能描述的,都可以继承。
例如:
Cat is a Animal:猫是一个动物
Dog is a Animal:狗是一个动物
CreditAccount is a Account:信用卡账户是一个银行账户
....
假设以后的开发中有一个A类,有一个B类,A类和B类确实也有重复的代码,
那么他们两个之间就可以继承吗?不一定,还是要看一看它们之间是否能够
使用is a来描述。
1.2、方法覆盖
方法覆盖又叫做:方法重写(重新编写),英语单词叫做:Override、Overwrite,都可以。
比较常见的:方法覆盖、方法重写、override
什么时候考虑使用方法覆盖?
父类中的方法无法满足子类的业务需求,子类有必要对继承过来的方法进行覆盖。
重要结论:
当子类对父类继承过来的方法进行“方法覆盖”之后,
子类对象调用该方法的时候,一定执行覆盖之后的方法。
什么条件满足的时候构成方法覆盖?
第一:有继承关系的两个类
第二:具有相同方法名、返回值类型、形式参数列表
第三:访问权限不能更低。
第四:抛出异常不能更多。
这里还有几个注意事项:(这几个注意事项,当学习了多态语法之后自然就明白了!)
注意1:方法覆盖只是针对于方法,和属性无关。
注意2:私有方法无法覆盖。
注意3:构造方法不能被继承,所以构造方法也不能被覆盖。
注意4:方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。
一定要注意:方法覆盖/重写的时候,建议将父类的方法复制粘贴,这样比较保险。
关于Object类中toString()方法的覆盖?
toString()方法存在的作用就是:将java对象转换成字符串形式。
Object类中toString()方法的默认实现是什么?
public String toString() {
return getClass().getName() + "@" + Integer.toHexString(hashCode());
}
toString: 方法名的意思是转换成String
含义:调用一个java对象的toString()方法就可以将该java对象转换成字符串的表示形式。
大多数的java类toString()方法都是需要覆盖的。因为Object类中提供的toString()
方法输出的是一个java对象的内存地址。
至于toString()方法具体怎么进行覆盖?
public String toString() {
return ......
}
格式可以自己定义,或者听需求的。(听项目要求的。)
方法重载和方法覆盖有什么区别?
方法重载发生在同一个类当中。
方法覆盖是发生在具有继承关系的父子类之间。
方法重载是一个类中,方法名相同,参数列表不同。
方法覆盖是具有继承关系的父子类,并且重写之后的方法必须和之前的方法一致:
方法名一致、参数列表一致、返回值类型一致。
方法重写的检查
@override
让编译器帮助我们检查当前的方法,是否是对父类中的方法进行重写
1.3、方法覆盖需要和多态机制联合起来使用才有意义。
Animal a = new Cat();
a.move();
要的是什么效果?
编译的时候move()方法是Animal的。
运行的时候自动调用到子类重写move()方法上。
假设没有多态机制,只有方法覆盖机制,你觉得有意义吗?
没有多态机制的话,方法覆盖可有可无。
没有多态机制,方法覆盖也可以没有,如果父类的方法无法满足
子类业务需求的时候,子类完全可以定义一个全新的方法。
方法覆盖和多态不能分开。
1.4、静态方法存在方法覆盖吗?
多态自然就和对象有关系了。
而静态方法的执行不需要对象。
所以,一般情况下,我们会说静态方法“不存在”方法覆盖。
不探讨静态方法的覆盖。
1.5、多态的基础语法
1、学习多态基础语法之前,我们需要普及两个概念:
第一个:向上转型(自动类型转换)
子 ---> 父
第二个:向下转型(强制类型转换,需要加强制类型转换符)
父 ---> 子
子类类型 子类类型的对象名 = (子类类型)父类类型的引用
注意:
java中允许向上转型,也允许向下转型。
*****(五颗星)无论是向上转型,还是向下转型,
两种类型之间必须有继承关系,没有继承关系编译器报错。
2、多态指的是:
父类型引用指向子类型对象。
包括编译阶段和运行阶段。
编译阶段:绑定父类的方法。(编译阶段属于静态绑定。)
运行阶段:动态绑定子类型对象的方法。(运行阶段绑定属于动态绑定。)
多种形态。
多态的典型代码:父类型的引用指向子类型的对象。
3、个别同学有点混乱了:
java中只有“类名”或者“引用”才能去“点”
类名.
引用.
万变不离其宗,只要你想“点”,“点”前面要么是一个类名,要么是一个引用。
4、什么时候必须使用“向下转型”?
不要随便做强制类型转换。
当你需要访问的是子类对象中“特有”的方法。此时必须进行向下转型。
1.6、java.lang.ClassCastException:类型转换异常
对象无继承关系
1.7、怎么避免ClassCastException(类型转换异常)风险?:instanceof (运行阶段动态判断)
第一:instanceof可以在运行阶段动态判断引用指向的对象的类型。
第二:instanceof的语法:
(引用.instanceof(类型))
第三:instanceof运算符的运算结果只能是:true/false
第四:c是一个引用,c变量保存了内存地址指向了堆中的对象。
程序员要养成一个好习惯:
任何时候,任何地点,对类型进行向下转型时,一定要使用
instanceof 运算符进行判断。(java规范中要求的。)
这样可以很好的避免:ClassCastException
不管是向上转型还是向下转型,首先他们之间必须有继承关系,这样编译器就不会报错。
1.8、多态在开发中有什么作用?
多态在开发中的作用是:
降低程序的耦合度,提高程序的扩展力。
在方法的参数列表中,可以定义父类类型的引用,将来调用的时候,对于父类类型下的所以的子类类型对象,都可 以作为实际参数
不在方法的参数列表中,就在普通的方法中,使用父类类型的引用指向子类的对象,也能提高代码的扩展性。
对象的来源是特别广泛的,不仅仅是new出来的
还可以是通过反射获取,或者文件读取,或者网络传递,在写代码的编译阶段,无法知道该对象具体的子类类型, 需要使用父类类型的引用操作不知道子类类型的对象。
面向对象的三大特征:
封装、继承、多态
真的是一环扣一环。
有了封装,有了这种整体的概念之后。
对象和对象之间产生了继承。
有了继承之后,才有了方法的覆盖和多态。
这里提到了一个软件开发原则:
七大原则最基本的原则:OCP(对扩展开放,对修改关闭)
目的是:降低程序耦合度,提高程序扩展力。
面向抽象编程,不建议面向具体编程。
1.9、私有方法无法覆盖。
方法覆盖只是针对于“实例方法”,“静态方法覆盖”没有意义。(这是因为方法覆盖通常和多态联合起来)
总结两句话:
私有不能覆盖。
静态不谈覆盖。
在方法覆盖中,关于方法的返回值类型。
什么条件满足之后,会构成方法的覆盖呢?
1、发生具有继承关系的两个类之间。
2、父类中的方法和子类重写之后的方法:
具有相同的方法名、相同的形式参数列表、相同的返回值类型。
学习了多态机制之后:
“相同的返回值类型”可以修改一下吗?
对于返回值类型是基本数据类型来说,必须一致。
对于返回值类型是引用数据类型来说,重写之后返回值类型可以变的更小(但意义不大,实际开发中没人这样写。)。
2.0、二维数组
两种初始化形式
格式1: 动态初始化
数据类型 数组名 [ ][ ] = new 数据类型[m][n]
数据类型 [ ][ ] 数组名 = new 数据类型[m][n]
数据类型 [ ] 数组名 [ ] = new 数据类型[m][n]
举例:int [ ][ ] arr=new int [5][3]; 也可以理解为“5行3例”
格式2: 静态初始化
数据类型 [ ][ ] 数组名 = {{元素1,元素2....},{元素1,元素2....},{元素1,元素2....}.....};
举例:int [ ][ ] arr={{22,15,32,20,18},{12,21,25,19,33},{14,58,34,24,66}};
访问: 数组名[a][b];
行数:arr.length;
列数:arr[0].length;
2.1、Java ArrayList---------->对数组长度有要求时使用
ArrayList 类是一个可以动态修改的数组,与普通数组的区别就是它是没有固定大小的限制,我们可以添加或删除元素。
ArrayList 继承了 AbstractList ,并实现了 List 接口。
ArrayList 类位于 java.util 包中,使用前需要引入它,语法格式如下:
注意首字母大写!
import java.util.ArrayList; // 引入 ArrayList 类
ArrayList<E> objectName =new ArrayList<>(); // 初始化
E: 泛型数据类型,用于设置 objectName 的数据类型,只能为引用数据类型。
objectName: 对象名。
添加元素:
添加元素到 ArrayList 可以使用 add() 方法:
实例:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites);
}
}
访问元素:
访问 ArrayList 中的元素可以使用 get() 方法:
注意:数组的索引值从 0 开始。
实例:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
System.out.println(sites.get(1)); // 访问第二个元素
}
}
修改元素:
如果要修改 ArrayList 中的元素可以使用 set(index,value) 方法:
实例:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.set(2, "Wiki"); // 第一个参数为索引位置,第二个为要修改的值
System.out.println(sites);
}
}
删除元素:
如果要删除 ArrayList 中的元素可以使用 remove() 方法:
实例:
import java.util.ArrayList;
public class RunoobTest {
public static void main(String[] args) {
ArrayList<String> sites = new ArrayList<String>();
sites.add("Google");
sites.add("Runoob");
sites.add("Taobao");
sites.add("Weibo");
sites.remove(3); // 删除第四个元素
System.out.println(sites);
}
}
更多操作:
https://www.runoob.com/java/java-arraylist.html
Java ArrayList 常用方法列表如下:
方法 描述
add() 将元素插入到指定位置的 arraylist 中
addAll() 添加集合中的所有元素到 arraylist 中
clear() 删除 arraylist 中的所有元素
clone() 复制一份 arraylist
contains() 判断元素是否在 arraylist
get() 通过索引值获取 arraylist 中的元素
indexOf() 返回 arraylist 中元素的索引值
removeAll() 删除存在于指定集合中的 arraylist 里的所有元素
remove() 删除 arraylist 里的单个元素
size() 返回 arraylist 里元素数量
注意是size。
isEmpty() 判断 arraylist 是否为空
subList() 截取部分 arraylist 的元素
set() 替换 arraylist 中指定索引的元素
sort() 对 arraylist 元素进行排序
comparator - 顺序方式
Comparator.naturalOrder()-----(自然顺序)升序
Comparator.reverseOrder()-----降序
toArray() 将 arraylist 转换为数组
语法为:arraylist.toArray(T[] arr)
T [] arr(可选参数)- 用于存储数组元素的数组 注意:这里 T 指的是数组的类型。
如果参数 T[] arr 作为参数传入到方法,则返回 T 类型的数组。如果未传入参数,则返回 Object 类型的数组。
一般转化都是把String类型的转化为String类型的数组;
这个方法要传入的参数T是泛型,但是泛型必须是引用类型,不能是基本类型(比如int)
所以如果要转化成int类型的数组:
声明一个Integer类型的数组:
Integer[] arr2=new Integer[arr.size];
现在就可以转: arr1.toArray(arr2);
toString() 将 arraylist 转换为字符串
ensureCapacity() 设置指定容量大小的 arraylist
lastIndexOf() 返回指定元素在 arraylist 中最后一次出现的位置
retainAll() 保留 arraylist 中在指定集合中也存在的那些元素
containsAll() 查看 arraylist 是否包含指定集合中的所有元素
trimToSize() 将 arraylist 中的容量调整为数组中的元素个数
removeRange() 删除 arraylist 中指定索引之间存在的元素
replaceAll() 将给定的操作内容替换掉数组中每一个元素
removeIf() 删除所有满足特定条件的 arraylist 元素
forEach() 遍历 arraylist 中每一个元素并执行特定操作
2.2、for (int i : arr) +JAVA语句;这个语句的意思
int[] arr = new int{1,2,3,4};
for{int i ;arr}{
.........
}
即为遍历arr这个数组,和for循环遍历一样
1.1、工具类的编写
1、工具类:在一个类中,主要的目的就是为了 快速的解决一些问题,而定义的一些方法,因此在工具类中没有必须维护成员变量。方法都是一些静态的方法。更方便的使用,解决问题。对于工具类就不需要创建对象。浪费内存。希望控制不让工具类创建对象。
eg:Arrays.
1.2、帮助文档的制作
1、工具类准备好之后,编译之后生成.class字节码文件,外界不能看懂,所以需要编写工具类的程序员,要准备一份工具类的帮助文档。
2、文档注释:用于给代码生成帮助文档的注释
格式:
/**
*文档注释的内容
*/
3、帮助文档的注解:将来可以被文档生成工具进行解析的一种格式。可以解析其中的数据
作者:@author fang
版本:@version 12
从那个版本开始:@since 1.0
参数:@param 参数名称 参数名称的解释
返回值:@return 返回内容的解释
4、生成帮助文档
使用jdk中bin目录下提供的javadoc这个工具,就可以生成帮助文档
javadoc -d arrayTool -author -version 源代码文件