JAVASE基础-语法


JAVASE基础-语法

关于java程序代码的解释说明

1
2
3
4
5
6
7
8
9
// 单行注释

/*
多行注释
*/

/**
* javadoc注释:这里的注释信息可以自动被javadoc.exe命令解析提取并生成到帮助文档当中。
*/

命名规范

规范1:见名知意(这个标识符在起名的时候,最好一看这个单词就知道啥意思。)

规范2:遵循驼峰命名方式,什么是驼峰(一高一低,一高一低...)
            驼峰有利于单词与单词之间很好的进行分隔
            BiaoShiFuTest,这个很好,一眼就能看出来是4个单词。

规范3:类名、接口名有特殊要求
            类名和接口名首字母大写,后面每个单词首字母大写。
                StudentTest、UserTest ,这是类名、接口名。

规范4:变量名、方法名有特殊要求
            变量名和方法名首字母小写,后面每个单词首字母大写。
                nianLing(NianLing这样就不符合了。)
                mingZi(MingZi这样也不符合了。)
        
规范5:所有“常量”名:全部大写,并且单词和单词之间采用下划线衔接。
            USER_AGE :用户年龄
            MATH_PI:固定不变的常量3.1415926.....

变量

1、关于变量的一个分类
    变量根据出现的位置进行划分:
        在方法体当中声明的变量:局部变量。
        在方法体之外,类体内声明的变量:成员变量。
        重点依据是:声明的位置。
2、注意:局部变量只在方法体当中有效,方法体执行结束该变量的内存就释放了。

数据类型

    类型            占用字节数量(byte)
    ------------------------------------
    byte                1
    short                2
    int                    4
    long                8
    float                4
    double                8
    boolean                1  (1byte的1或0,00000001(true)或00000000(false))
    char                2
注意:任何浮点型容量大于整数型:float>long
有几个取值范围需要大家记住:
    (1个字节)byte: [-128 ~ 127]
    (2个字节)short:[-32768 ~ 32767] 可以表示65536个不同的数字
    (4个字节)int: [-2147483648 ~ 2147483647]
    (2个字节)char: [0~65535]  可以表示65536个不同的数字
    short和char实际上容量相同,不过char可以表示更大的数字。因为char表示的是文字,文件没有正负之分,所以char可以表示更大的数字。

java中规定,任何一个浮点型数据默认被当做double来处理。如果想让这个浮点型字面量被当做float类型来处理,那么请在字面量后面添加F/f。
float f = 3.14;错误: 不兼容的类型: 从double转换到float可能会有损失
修改:float f = 3.14f;or float f = (float)3.14;(可能损失精度)

字符编码

字符编码其实本质上就是一本字典,该字段中描述了文字与二进制之间的对照关系。字符编码涉及到编码和解码两个过程,编码和解码的时候必须采用同一套字符编码方式,不然就会出现乱码。
需要记住:
        ASCII        ('a'是97 'A'是65 '0'是48...)
        ISO-8859-1    (latin-1)
        GB2312
        GBK
        GB18030       (GB2312<GBK<GB18030 (容量的关系))
        Big5        (繁体)
        unicode        (支持所有文字,体的实现包括:utf8 utf16 utf32)

整数

在任何情况下,整数型的“字面量/数据”默认被当做int类型处理。如果希望该“整数型字面量”被当做long类型来处理,需要在“字面量”后面添加L/l。建议使用大写L。

1
2
3
4
5
6
7
8
9
10
11
12
long d = 2147483647; // 2147483647是int最大值。
System.out.println(d);
// 编译器会报错吗?为什么?
// 在java中,整数型字面量一上来编译器就会将它看做int类型
// 而2147483648已经超出了int的范围,所以在没有赋值之前就出错了。
// 记住,不是e放不下2147483648,e是long类型,完全可以容纳2147483648
// 只不过2147483648本身已经超出了int范围。
// 错误: 整数太大
//long e = 2147483648;

// 怎么解决这个问题呢?
long e = 2147483648L;

二进制原码、反码、补码

1、计算机在任何情况下都只能识别二进制
2、计算机在底层存储数据的时候,一律存储的是“二进制的补码形式”计算机采用补码形式存储数据的原因是:补码形式效率最高。

1
2
3
4
5
6
7
8
9
10
对于一个正数来说:二进制原码、反码、补码是同一个,完全相同。
int i = 1;
对应的二进制原码:00000000 00000000 00000000 00000001
对应的二进制反码:00000000 00000000 00000000 00000001
对应的二进制补码:00000000 00000000 00000000 00000001
对于一个负数来说:二进制原码、反码、补码是什么关系呢?
byte i = -1;
对应的二进制原码:10000001
对应的二进制反码(符号位不变,其它位取反):11111110
对应的二进制补码(反码+1):11111111

综合的看,在类型转换的时候需要遵循哪些规则?

第一条:八种基本数据类型中,除 boolean 类型不能转换,剩下七种类型之间都可以
进行转换;

第二条:如果整数型字面量没有超出 byte,short,char 的取值范围,可以直接将其赋
值给byte,short,char 类型的变量;

第三条:小容量向大容量转换称为自动类型转换,容量从小到大的排序为:
byte < short(char) < int < long < float < double,其中 short和 char 
都占用两个字节,但是char 可以表示更大的正整数;

第四条:大容量转换成小容量,称为强制类型转换,编写时必须添加“强制类型转换符”,
但运行时可能出现精度损失,谨慎使用;

第五条:byte,short,char 类型混合运算时,先各自转换成 int 类型再做运算;

第六条:多种数据类型混合运算,各自先转换成容量最大的那一种再做运算;

所有的笔试题都超不出以上的6条规则。

运算符

逻辑运算符

    &    逻辑与(可以翻译成并且)
    |    逻辑或(可以翻译成或者)
    !    逻辑非(取反)
    &&    短路与
    ||    短路或(短路:条件充分时不读取右表达式)
用普通话描述的话:100 大于 99 并且 100 大于 98 ,有道理
用代码描述的话:100 > 99 & 100 > 98 --> true
true & true --> true
非常重要:
    逻辑运算符两边要求都是布尔类型,并且最终的运算结果也是布尔类型。
    这是逻辑运算符的特点。

赋值运算符

1
2
3
4
5
6
7
8
9
10
基本赋值运算符?
=
扩展的赋值运算符?
+=
-=
*=
/=
%=
使用扩展赋值运算符的时候,永远都不会改变运算结果类型。
如byte x = 100;时, x += 1 等同于:x = (byte)(x + 1);而使用x = x + 1错误: 不兼容的类型: 从int转换到byte可能会有损失。

+运算符

1
2
3
4
5
6
7
8
9
什么时候求和?什么时候进行字符串的拼接呢?
当 + 运算符两边都是数字类型的时候,求和。
当 + 运算符两边的“任意一边”是字符串类型,那么这个+会进行字符串拼接操作。字符串拼接完之后的结果还是一个字符串。
注意:当一个表达式当中有多个加号的时候遵循“自左向右”的顺序依次执行(除非额外添加了小括号,小括号的优先级高)。
如:
int a = 100;
int b = 200;
System.out.println(a + "+" + b + "=" + a + b); "100+200=100200"
System.out.println(a + "+" + b + "=" + (a + b)); "100+200=300"

输入

1
2
3
4
5
前提:java.util.Scanner s = new java.util.Scanner(System.in); // s 变量名,可以修改。其它不能改。
接收一个整数
int num = s.nextInt();
接收一个字符串
String str = s.next();

控制语句

if

1
2
3
4
if语句的语法格式:
if(布尔表达式){
java语句;
}

switch

1
2
3
4
5
6
7
switch(值){
case 值1:
java语句;...
break;
default:
java语句;
}
switch语句支持的值有哪些?
            支持int类型以及String类型。
            但一定要注意JDK的版本,JDK8之前不支持String类型,只支持int。
            在JDK8之后,switch语句开始支持字符串String类型。
switch语句本质上是只支持int和String,但是byte,short,char也可以
                使用在switch语句当中,因为byte short char可以进行自动类型转换。
                switch语句中“值”与“值1”、“值2”比较的时候会使用“==”进行比较。

for

1
2
3
4
5
6
7
for(初始化表达式; 条件表达式; 更新表达式){
循环体; // 循环体由java语句构成
....
}
条件表达式结果必须是一个布尔类型,也就是:true或false。
初始化表达式属于for循环域,for循环结束其内存就释放了,for循环域之外没有办法直接使用。

while

1
2
3
4
while(布尔表达式){
循环体;
}
循环次数可能为0次

do..while

1
2
3
4
do {
循环体;
}while(布尔表达式);
循环体至少执行1次。

break 和 continue新特性

1
2
3
4
5
6
7
8
9
//break终止指定循环,continue同理
a:for(int k = 0; k < 2; k++){
b:for(int i = 0; i < 10; i++){
if(i == 5){
break a; // 终止指定的循环。
}
System.out.println("i ===> " + i);
}
}

方法与递归

方法

​ 方法(英语单词:method)是可以完成某个特定功能的并且可以被重复利用的代码片段。
​ 在C语言中,方法被称为“函数”。在java中不叫函数,叫做方法。

命名

​ 方法名要见名知意。(驼峰命名方式)
​ 方法名在标识符命名规范当中,要求首字母小写,后面每个单词首字母大写。
​ 只要是合法的标识符就行。

方法定义和语法

1
2
3
[修饰符列表] 返回值类型 方法名(形式参数列表){
方法体;
}

[] 符号叫做中括号,以上中括号[]里面的内容表示不是必须的。

当一个方法执行结束不返回任何值的时候,必须写上void关键字,表示该方法执行结束后不返回任何结果。方法体当中可以有“return;”语句用来终止当前方法。

如果返回值类型“不是void”,那么在方法体执行结束的时候必须使用”return 值;”来完成“值”的返回,如果没有“return 值;”编译器会报错。只要有“return”关键字的语句执行,当前方法必然结束。

方法调用

类名.方法名(实际参数列表);

a()方法调用b()方法的时候,a和b方法都在同一个类中,“类名.”可以省略。如果不在同一个类中“类名.”不能省略。

方法执行时内存变化

方法调用的时候,该方法需要的内存空间在栈中分配。

方法只有在调用的时候才会在栈中分配空间,并且调用时就是压栈。

方法执行结束之后,该方法所需要的空间就会释放,此时发生弹栈动作。

方法调用叫做:压栈。分配空间;方法结束叫做:弹栈。释放空间

栈中存储什么?方法运行过程中需要的内存,以及栈中会存储方法的局部变量。

使用例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public class MethodTest{
//主方法,入口
public static void main(String[] args){

//int a = 100;
// 这个赋值原理是:将a变量中保存的100这个数字复制一份传给b变量。
// 所以a和b是两个不同的内存空间,是两个局部变量。
//int b = a;

System.out.println("main begin");
int x = 100;
m1(x);
System.out.println("main over");
}
public static void m1(int i){ // i是局部变量
System.out.println("m1 begin");
m2(i);
System.out.println("m1 over");
}
public static void m2(int i){
System.out.println("m2 begin");
m3(i);
System.out.println("m2 over");

}
public static void m3(int i){
System.out.println("m3 begin");
System.out.println(i);
System.out.println("m3 over");
}
}

方法重载机制

“功能相似”的,可以让“方法名相同”,更易于以后的代码编写。

在java语言中进行方法区分,首先java编译器会通过方法名进行区分。如果方法名相同,编译器会通过方法的参数类型进行方法的区分。

使用条件
条件1:在同一个类当中
条件2:方法名相同
条件3:参数列表不同:参数的个数不同,或参数的类型不同;或参数的顺序不同。

使用例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
public class OverloadTest02{
public static void main(String[] args){
// 对于程序员来说,只需要记忆一个方法名即可。
System.out.println(sum(10, 20));
System.out.println(sum(10L, 20L));
System.out.println(sum(10.0, 20.0));
}
// 定义一个计算int类型数据的求和方法
public static int sum(int a, int b){
System.out.println("int求和");
return a + b;
}

// 定义一个计算long类型数据的求和方法
public static long sum(long a, long b){
System.out.println("long求和");
return a + b;
}

// 定义一个计算double类型数据的求和方法
public static double sum(double a, double b){
System.out.println("double求和");
return a + b;
}
}

注意:

方法重载和方法的“返回值类型”无关。

1
2
3
4
5
6
7
public static int m5(){
return 1;
}
public static double m5(){
return 1.0;
}
//方法重复

方法重载和方法的“修饰符列表”无关。

1
2
3
4
5
void m6(){
}
public static void m6(){
}
//方法重复

递归

栈内存溢出错误:StackOverflowError,可以调大栈内存的空间。

(java -X)这个可以查看调整堆栈大小的参数。