目录
一、运行HelloWorld程序
1、运行步骤
编写(.java)——编译(.class)——运行
2、代码
public class Test1
{
public static void main(String[] args){
System.out.println("HelloWorld!");
}
}
3、语法注意事项
1、严格区分大小写
2、每句命令结尾使用分号
3、符号都是英文状态
4、括号、引号都是成对出现的!
5、注意缩进
Tips1:文件名和类名必须一致吗?
可以不一致,但public修饰的类必须和文件名一致!
Tips2:
1、同一个java文件下,有几个class就有几个“.class”文件
2、同一个java文件下,只能有一个public class 类,并且该类的类名必须与java文件的文件名一致。
3、当java下有很多类时,可以使用 java + 编译好的类进行使用。
二、注释
1、单行注释
//注释文字
特点:只针对当前行有效
一般用于放在指令的行尾。
2、多行注释
/*
注释文字
*/
特点:可以针对多行有效
一般用于放在指令的上方
3、文档注释(Java特有)
/**
注释文字
*/
三、转义字符
特点:一般用在类或方法的上方,可以在帮助文档中显示
说明:\n表示形式:+符号
常见的转义字符:
- \n 换行符
- \t 制表符
- \' 一个 ' 如: System.out.println("性别:\'男\' ");
- \" 两个 " 如:System.out.println("姓名:\"张三\" ");
- \r 在当前行的最前面进行显示。前面有数据则进行覆盖。 如:System.out.println("你是一只小狗\r它是"); 输出结果:它是一只小狗
四、变量
1、定义:内存中的一块数据存储空间的表示
①变量的分类:基本数据类型和引用(复杂)数据类型--------------(按照类型分类)
② 变量的分类-按声明的位置的不同
在方法体外,类体内声明的变量称为成员变量。
在方法体内部声明的变量称为局部变量。
③上述两种分类需要注意的地方:
二者在初始化值方面的异同:
同:都有生命周期
异:局部变量除形参外,需显式初始化。
2、变量三要素:数据类型、变量名、存储的数据
要素一:数据类型
数据总类型 | 类型 | 存储需求 | 取值范围 |
整型 | byte | 1个字节 | -128~127 |
short | 2 | -32768~32767 [-2^15 ~(2^15) -1] | |
int(默认) | 4 | -2147483648~2147483647(正好超过20亿)[-2^31 ~ (2^31)-1 (约21亿)] | |
long | 8 | -9223372036854775808~9223372036854775807[-2^63 ~ (2^63)-1] | |
浮点型 | float | 4 | 大约+ 3.40282347E+38F(有效位数为6~7位)[-3.403E38 ~ 3.403E38 ] |
double(默认) | 8 | 大约+ 1.79769313486231570E+308(有效位数为15位)[-1.798E308 ~ 1.798E308] | |
字符型 | char | 2 | 单个字符 |
布尔型 | boolean | 1 | true、false |
前言:
字节和位的转换:1字节 = 8位(bit)
- 整型
byte
int
short
long
特点:
1、编译器默认的整型类型是int
2、如果希望将整型的常量值表示成long类型,则需要使用标记l或L
3、每种类型存储的常量值必须在能表述的范围内,否则报错!
- 浮点型: 符号位+指数位+尾数位(转为二进制的方法)
float
double
double 类型除于0, 不会出现编译错误,结果是无穷大的(Infinty)
//double 类型除于0, 不会出现编译错误,结果是无穷大的(Infinty)
class Test01_ReviewDouble{
public static void main(String[] args){
int d1 = 1;
int d2 = 0;
System.out.println(d1/d2);
}
}
特点:
1、编译器默认的浮点型是double,如果希望当做float,则通过f或F标记;
2、浮点数在计算机底层的存储,会丢失精度,所得出的数是一个无限接近于真值的数。
如果希望提高精确度,可以用BigDecimal类
3、浮点数的常量值的表示形式:
1.5 1.5f .5
1.5e2
- 字符型(底层就是int型)
char
char | 所占空间 | 使用的字符编码 |
2个字节 | unicode |
补充:编码表
ASCII码表,只能表示128个字符,单字节编码表 a-z(97-123) \ A-Z (65-91) \ 0-9
unicode码表,可以表示所有的符号,固定双字节编码表
utf-8码表,可以表示所有的符号,可变字节长度编码表
一个英文字母,占1个字节;一个汉字,占3个字节
GBK码表,可以表示中文,但不能表示世界上所有符号
一个英文字母,占1个字节,一个汉字,占2个字节
特点:
char类型的常量值可以是用单引号引起来的单个字符,也可以是一个unicode码值,也可以是一个整型的常量值
①字符型的底层存储都是以整数形式
存储: 字符——>unicode码表找到对应的二进制整数——>存储
读取:二进制整数——>unicode码表找到对应的字符——>读取
②字符串的常量值表示形式
- 布尔型
特点:
boolean类型的变量一般用于条件判断中,比如if分支结构、循环结构
要素二:标识符
1、标识符的命名规则有哪些?
不遵守,编译不通过。
> 由26个英文字母大小写,0-9 ,_或 $ 组成
> 数字不可以开头。
> 不可以使用关键字和保留字,但能包含关键字和保留字。
> Java中严格区分大小写,长度无限制。
> 标识符不能包含空格。
2、标识符的命名规范有哪些?不遵守,编译运行都可以通过
包名:xxxyyyzzz
类名、接口名:XxxYyyZzz
变量名、方法名:xxxYyyZzz
常量名:XXX_YYY_ZZZ
3、关键字与保留字
Java保留字:
现有Java版本尚未使用,但以后版本可能会作为关键字使 用。自己命名标识符时要避免使用这些保留字
byValue, cast, false, future, generic, inner, operator, outer, rest, true, var , goto ,const,null
注意:true、false、null(是指的值,不是关键字)
要素三:存储的数据
常量值或字面值
3、变量的数据转换
1、基本数据类型转换
1.1自动类型转换(小---->大)
语法: 无(可以自动转换)
1.2强制类型转换(大---->小)
语法:数据类型 变量名 = (目标类型)数值
符号:()
注意:强转只对就近的作用
如:byte a = (byte)3.5 * 10 + 2.5 * 20; //依旧编译出错
更改为:byte a = (byte)(3.5 * 10 + 2.5 * 20); //编译正确
1.3数据类型默认情况
①整型数值默认为:int
②byte、short、char 之间进行运算,结果值的类型为int
③注意拼接运算,“看到底是先运算还是先拼接”
如:System.out.println("hello"+'a'+12); //helloa12
System.out.println('a'+12+"hello"); //109hello
2、基本类型与String之间的转换
2.1 基本类型-->String
规则:直接拼接空字符串即可
示例:
int a = 100;
String s = a+""; // 100(String类型)
2.2 String--> 基本类型
规则:类型.praseXXX(需要转换的内容)
①转为boolean,只要是非true的值,结果都是false
②String类不能转换为char
示例:
int i = Integer.parseInt(str);
3、问题
问题一:
说明基本数据类型变量之间自动类型提升的运算规则。
byte、short、char ---》int---》long----》float ----》double
结论:当容量小的数据类型的变量与容量大的数据类型的变量做运算时,结果自动提升为容量大的数据类型。
byte 、char 、short --> int --> long --> float --> double
特别的:当byte、char、short三种类型的变量做运算时,结果为int型
问题二:
说明基本数据类型变量之间强制类型转换的使用规则和强转可能出现的问题。
容量大 --》 容量小
使用强转符:()
精度损失。
五、运算符
(1)算数运算符
1、基本算数运算符
种类: + - * / %
特点:
①/左右的操作数如果都是整型,则结果取整
②"%": a%b = a-(int)a/b*b(取余公式)
13.5%3=13.5- 13/3*3=1.5
-13%-3= -13 - (-13)/3*3 = -1
③属于二元操作符,运算顺序:从左往右
算术表达式的结果肯定是数值型
2、自增、自减算数运算符(一元运算符)(重点:易出题)
①属于一元操作符
i++;
--i;
++i
i--;
int j = i++;
②既可以作为独立语句使用,又可以作为表达式使用
如果作为独立语句使用,则i++;等价于++i;等价于i=i+1;
如果作为表达式使用,则 ★
int j= i++; 先赋值后自增
int j= ++i; 先自增后赋值
③自增、自减运算符,编译器做了内部的优化,会进行自动的类型转换,而且效率也提高了
byte b = 1;
b++;//不会报编译错误!
注意:
和i = i + 1;不一样的地方
如: byte i = 1; i = i + 1; //int 与 byte 类型不兼容的编译错误
(2)关系运算符(二元运算符)
种类: > < >= <= == !=
特点:
①属于二元操作符
②关系表达式的结果类型肯定是 boolean类型
③关系表达式一般当作条件放在if结构或循环结构中
(3)逻辑运算符(重点:易出题)
符号 | 名称 | 写法 | 特点 |
&& | 短路与 | 条件1 && 条件2 | 两个条件都成立,结果为true |
|| | 短路或 | 条件1 || 条件2 | 只要有一个条件成立,结果为true |
! | 非 | !条件 | 如果条件本身成立,结果为false |
& | 逻辑与 | 条件1 & 条件2 | 两个条件都成立,结果为true |
| | 逻辑或 | 条件1 | 条件2 | 只要有一个条件成立,结果为true |
异或( ^ )与或( | )的不同之处是:当左右都为true时,结果为false。 理解:异或,追求的是“异”!
&&和&的区别:
&& 如果第一个条件不成立,则不再判断第二个条件,直接结果为false
& 不管第一个条件是否成立,都要判断第二个条件
||和|的区别:
|| 如果第一个条件成立,则不再判断第二个条件,直接结果为true
| 不管第一个条件是否成立,都要判断第二个条件
(4)赋值运算符
特点:
①赋值运算符的运算顺序从右往左
②赋值号左边只能是变量,右边可以是常量、变量、表达式、方法调用
③ 复合赋值运算符的细节:
int x = 1;
x+=10; 等价于 x = (int)(x+10);
复合赋值运算符底层做了优化,进行了内部强转,效率较高!
复合赋值运算符,要求左边的变量必须已经初始化
小Tips:对于变量来讲,变量必须先声明,赋值,最后才能使用!!!
a、基本赋值运算符
=
b、复合赋值运算符
+= -= *= /= %= >>= <<= ^=
如:
x *= 1.5;相当于 x = (int)(x*1.5) 后者存在类型兼容问题,前者是优化之后,不存在。
(5)三元运算符(三目运算符)
格式: 条件表达式?表达式1 :表达式2
运算规则:判断条件表达式的结果是否成立,如果成立,则执行表达式1,否则执行表达式2
注意事项:
1、只能作为表达式使用
2、表达式1和表达式2的类型必须一致或兼容
10 <-> 1.5 兼容
10 <-> 'a' 兼容
true <-> 'a' 不兼容
"john" <-> 10 不兼容
3、如果条件成立,则执行表达式1,表达式2根本不执行
如果条件不成立,则执行表达式2,表达式1根本不执行
(6)位运算符
计算机底层都是以二进制的补码形式存储和运算的!!
原码:最高位为符号位,0代表正;1代表负。将十进制数进制转换得来
反码:对于正数,原码和反码一样
对于负数,最高位不变,其他位取反
补码:对于正数,原码和补码一样
对于负数,反码+1
常见的位运算符:
a<<b 左移:将a左移指定的b位,空缺位补0
a>>b 右移:将a右移指定的b位,空缺位补符号位
a>>>b无符号右移:将a右移指定的b位,空缺位补0
a&b与:两位都为1,结果为1,反之为0
a|b或:两位都为0,结果为0,反之为1
(7)运算符的优先级
只需记住 “ ( )” 是优先级最高的!!!
l 运算符有不同的优先级,所谓 优先级就是表达式运算中的运 算顺序。
如下表,上一行运算 符总优先于下一行。
l 只有单目运算符、三元运算符、 赋值运算符是从右向左运算的。
(8)题型
思考1:
short s = 3;
s = s+2; ①
s += 2;
② ①和②有什么区别?
思考2:
int i = 1;
i *= 0.1;
System.out.println(i);//
i++;
System.out.println(i);//
思考3:
int m = 2;
int n = 3;
n *= m++;
System.out.println("m=" + m);
System.out.println("n=" + n);
思考4:
int n = 10;
n += (n++) + (++n);
System.out.println(n);
练习:请写出每题的输出结果
1、
int x = 1;
int y=1;
if(x++==2 & ++y==2){
x =7;
}
System.out.println("x="+x+",y="+y);
2、
int x = 1,y = 1;
if(x++==1 | ++y==1){
x =7;
}
System.out.println("x="+x+",y="+y);
3、
int x = 1,y = 1;
if(x++==1 || ++y==1){
x =7;
}
System.out.println("x="+x+",y="+y);
4、
int x = 1,y = 1;
if(x++==2 && ++y==2){
x =7;
}
System.out.println("x="+x+",y="+y)
5、
1. class Test {
2. public static void main (String [] args) {
3. boolean x=true;
4. boolean y=false;
5. short z=42;
6. //if(y == true)
7. if((z++==42)&&(y=true))z++;
8. if((x=false) || (++z==45)) z++;
9.
10. System. out.println(“z=”+z);
11. }
12. }
结果为: 46
六、进制(了解)
(1)简介
所有数字在计算机底层都以二进制形式存在。
对于整数,有四种表示方式:
Ø二进制(binary):0,1 ,满2进1.以0b或0B开头。
Ø十进制(decimal):0-9 ,满10进1。
Ø八进制(octal):0-7 ,满8进1. 以数字0开头表示。
Ø十六进制(hex):0-9及A-F,满16进1. 以0x或0X开头表示。此处的A-F不区分大小写。 如:0x21AF +1= 0X21B0
(2)二进制
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;
当是long类型时,二进制默认占64位,第64位是符号位
二进制的整数有如下三种形式:
Ø原码:直接将一个数值换成二进制数。最高位是符号位
Ø负数的反码:是对原码按位取反,只是最高位(符号位)确定为1。
Ø负数的补码:其反码加1。
计算机以二进制补码的形式保存所有的整数。
Ø正数的原码、反码、补码都相同 Ø负数的补码是其反码+1
(3)进制间的转换
1、二进制 转 八进制和十六进制
2、十进制 转 八进制 和 十六进制
3、八进制、十六进制 转 二进制
4、二进制转十进制
七、原码、补码、反码
所有数字在计算机底层都以二进制形式存在。一个数在计算机中的二进制表示形式, 叫做这个数的机器数。机器数是带符号的,在计算机用一个数的最高位存放符号, 正数为0, 负数为1。
Java整数常量默认是int类型,当用二进制定义整数时,其第32位是符号位;当是long类型时,二进制默认占64位,第64位是符号位。
因为机器数是带符号的,因此机器数与一个数的“二进制值”还是有区别的。
计算机以补码的形式保存所有的整数。
正数的原码、反码、补码都相同
负数的补码是其反码加1。
1、原码
原码即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
2、反码
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
3、补码
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
为什么要使用原码、反码、补码表示形式呢?
计算机辨别"符号位"显然会让计算机的基础电路设计变得十分复杂! 于是人们想出了将符号位也参与运算的方法. 我们知道, 根据运算法则减去一个正数等于加上一个负数, 即: 1-1 = 1 + (-1) = 0 , 所以机器可以只有加法而没有减法, 这样计算机运算的设计就更简单了.
0000 0000:0 0000 0001 ~ 0111 1111 : 1~ 127 1000 0001 ~ 1111 1111 : -127 ~ -1 1000 0000:-128 (-127) - (1) = -128 (1000 0001 - (0000 0001)= (1000 0000) |
特殊值:
-1-127的结果应该是-128, 在用补码运算的结果中, [1000 0000]补 就应该是-128.
但是此时-128,如果用补码到反码,再到原码去计算是不对的,所以-128是个特殊值,记住它
补充:
(1)
//自增特例
class Test02_Iadd{
public static void main(String[] args){
int i = 1;
/*(1)先算右边
①先取i的值,放到“操作数栈”中
②修改i变量的值,加1 i=2
(2)再算赋值
把刚才“操作数栈”中值赋值给i i=1
*/
i = i++;
System.out.println(i);
}
}
(2)
// 自增运算问题
class Test03_Iadd2{
public static void main(String[] args){
int i = 1;
/*
(1)先算右边
①i++
A:先取i的值“1”,放到“操作数栈”中
B:立刻自增 i=2
②++i
A:先自增 i = 3
B:再取出目前i的值“3”,放到“操作数栈”中
③i++
A:先取i的值“3”,放到“操作数栈”中
B:立刻自增 i=4
④先算乘法
先弹出最上面的两个进行乘法运算,结果是9,然后把9压回去“操作数栈”中
⑤再算加法
把“操作数栈”中 9 和 1进行加法 = 10
(2)把最后的结果赋值给j
*/
int j = i++ + ++i * i++;
System.out.println(i);
System.out.println(j);
}
}
(3)
//自增运算问题
class Test04_Iadd3{
public static void main(String[] args){
int j = 1;
/*
j += ++j * j++;相当于
j = j + (++j * j++);
(1)先算右边
①先取j=1的值
②++j
A:j自增 j=2
B:取j=2的值
③j++
A:先取j=2的值
B:自增j=3
④乘法
2*2 = 4
⑤加法
1 + 4
⑥赋值
j = 5
*/
j += ++j * j++;
System.out.println(j);
}
}