目录
Java语言跨平台性原理
- 跨平台:任何软件的运行,都必须运行在操作系统上,而我们用Java编写的软件可以运行在任何的操作系统上,这个特性称为Java语言的跨平台特性。该特性是由JVM实现的,我们编写的程序运行在JVM上,而JVM运行在操作系统上。
- JVM(Java Virtual Machine ):Java虚拟机,简称JVM,是运行所有Java程序的假想计算机,是Java程序的运行环境之一,也是Java 最具吸引力的特性之一。我们编写的Java代码,都运行在JVM 之上。
- 跨平台的实质:每个操作系统下都有不同版本的虚拟机
-
JDK (Java Development Kit):是Java程序开发工具包,包含
JRE
和开发人员使用的工具。 -
JRE (Java Runtime Environment) :是Java程序的运行时环境,包含
JVM
和运行时所需要的核心类库
。
我们想要运行一个已有的Java程序,那么只需安装
JRE
即可。我们想要开发一个全新的Java程序,那么必须安装
JDK
,其内部包含JRE
。
入门程序 HelloWorld
程序开发步骤说明
Java程序开发三步骤:编写、编译、运行。
- 编写源程序.java文件
- 编译:javac Java源文件名.后缀名,产生字节码文件
- 运行:java 类名字
HelloWorld案例常见错误
- 单词拼写问题
- Java语言是一门严格区分大小写的语言
- 标点符号使用问题
- 不能用中文符号,英文半角的标点符号(正确)
- 括号问题,成对出现
编写Java程序时注意的问题
编码过程:字符转换为二进制的数值
解码过程:将二进制数值转换为字符
乱码:编码和解码过程中使用的字符集不一致。
1.字符编码问题
当cmd命令行窗口的字符编码与.java源文件的字符编码不一致,如何解决?
解决方案一:
在Notepad++等编辑器中,修改源文件的字符编码
解决方案二:
在使用javac命令式,可以指定源文件的字符编码
javac -encoding utf-8 Java源文件名.后缀名
2.一个源文件中是否可以有多个类?public呢?
一个源文件中可以有多个类,编译后会生成多个.class字节码文件。
但是一个源文件只能有一个public的类。
3.main必须在public的类中吗?
不是。
但是后面写代码时,基本上main习惯上都在public类中。
注释(comment)
注释的概念:在编写程序的过程中,对程序代码进行解释说明。
-
代码本身和人类的自然语言相比,可读性肯定是要差一些,所以为了更快能够知道代码的含义、作用、需要注意地方,所有程序员都应该养成写注释的好习惯。
-
由于注释的内容是给程序员看的,需要使用人类的自然语言,而自然语言又不符合编程语言的语法,所以必须通过特定的符号,标记出来这部分的内容是注释,而不是要执行的程序的代码。
- 注释:就是对代码的解释和说明。其目的是让人们能够更加轻松地了解代码。为代码添加注释,是十分必须要的,它不影响程序的编译和运行。
- Java中有
单行注释
、多行注释
和文档注释
- 单行注释以
//
开头,以换行结束 -
多行注释以
/*
开头,以*/结束
-
多行注释不能嵌套
-
-
文档注释以
/**
开头,以*/
结束-
Javadoc命令可以抽取每个类、方法中的文档注释,生成API手册
-
- 单行注释以
/**
这里是一个文档注释,通常包括对类或方法的介绍,还有作者、日期等信息。
类名:HelloWorld
整个程序执行的入口:main函数
*/
public class HelloWorld{
/*
多行注释:注释内容可以分很多行编写
注意:多行注释不能嵌套,嵌套会导致多行注释提前结束
main函数是整个程序的入口
main函数的声明格式是固定的
每一个类中最多只能有一个main函数*/
public static void main(String[] args){
// 单行注释:在命令行窗口内打印一句话
// 单行注释仅对当前行有效
}
}
关键字(KeyWord)
关键字:是指在程序中,Java已经定义好的单词,具有特殊含义。
-
HelloWorld案例中,出现的关键字有
public
、class
、static
、void
等,这些单词已经被Java定义好 -
关键字的特点:全部都是
小写字母
。
关键字一共50个,其中const和goto是保留字。
true,false,null看起来像关键字,但从技术角度,它们是特殊的布尔值和空值。
标识符( identifier)
简单的说,凡是程序员自己命名的部分都可以称为标识符。
即给类、变量、方法、包等命名的字符序列,称为标识符。
1、标识符的命名规则(必须遵守)
规则是硬性规定:一旦违反,程序就会在编译过程中报错
(1)Java的标识符只能使用26个英文字母大小写,0-9的数字,下划线_,美元符号$
(2)不能使用Java的关键字(包含保留字)和特殊值
(3)数字不能开头
(4)不能包含空格
(5)严格区分大小写
2、标识符的命名规范(行业共识)
(1)见名知意
(2)类名、接口名等:每个单词的首字母都大写,形式:XxxYyyZzz,
例如:HelloWorld,String,System等
(3)变量、方法名等:从第二个单词开始首字母大写,其余字母小写,形式:xxxYyyZzz,
例如:age,name,bookName,main
(4)包名等:每一个单词都小写,单词之间使用点.分割,形式:xxx.yyy.zzz,
例如:java.lang
(5)常量名等:每一个单词都大写,单词之间使用下划线_分割,形式:XXX_YYY_ZZZ,
例如:MAX_VALUE,PI
数据类型(data type)
数据类型分类
Java的数据类型分为两大类:
-
基本数据类型:包括
整数
、浮点数
、字符
、布尔
。 -
引用数据类型:包括
类
、数组
、接口
。
基本数据类型
四类八种基本数据类型:
Java中的默认类型:整数类型是
int
、浮点类型是double
。
-
常量整数值,
赋值给byte,只要在byte范围内即可。
赋值给short,只要在short范围即可。
赋值给int,只要在int范围即可。
赋值给long,在int范围内的,可以加也可以不用加L,会自动升级为long,如果数字超过int范围,必须加L。 -
小数常量值,无论多少,不加F/f,就是double类型。
常量(constant)
-
常量:在程序执行的过程中,其值不可以发生改变的量
-
常量的分类:
-
自定义常量:通过final关键字定义
-
字面值常量:
-
字面值常量 | 举例 |
---|---|
字符串常量 | ”Hello World!“ |
整数常量 | 6 |
浮点常量 | 6.6 |
字符常量 | 's','i','x' |
布尔常量 | true,false |
空常量 | null |
变量(variable)
变量:在程序执行的过程中,其值可以发生改变的量
变量的作用:用来存储数据,代表内存的一块存储区域,这块内存中的值是可以改变的。
变量的三要素
1、数据类型
2、变量名
3、值
变量的使用应该注意什么?
1、先声明后使用
如果没有声明,会报“找不到符号”错误
2、在使用之前必须初始化
如果没有初始化,会报“未初始化”错误
3、变量有作用域
如果超过作用域,也会报“找不到符号”错误
4、在同一个作用域中不能重名
变量的声明和赋值、使用的语法格式
1、变量的声明的语法格式:
数据类型 变量名;
例如:
int age;
String name;
double weight;
char gender;
boolean isMarry;
2、变量的赋值的语法格式:
变量名 = 值;
例如:
age = 18;
name = "灰二"; //字符串的值必须用""
weight = 60;
gender = '男';//单字符的值必须使用''
isMarry = false;
3、变量的使用的语法格式:
通过变量名直接引用
例如:
(1)输出变量的值
System.out.println(age);
System.out.println(name);
System.out.println(weight);
System.out.println(gender);
System.out.println(isMarry);(2)计算
age = age + 1;//年龄增加1岁
long类型:如果赋值的常量整数超过int范围,那么需要在数字后面加L。
float类型:如果赋值为常量小数,那么需要在小数后面加F/f。
char类型:使用单引号''
String类型:使用双引号""
两种常见的输出语句
-
换行输出语句:输出内容,完毕后进行换行,格式如下:
System.out.println(输出内容);
-
直接输出语句:输出内容,完毕后不做任何处理,格式如下
System.out.print(输出内容);
注意事项:
换行输出语句,括号内可以什么都不写,只做换行处理
直接输出语句,括号内什么都不写的话,编译报错
如果()中有多项内容,那么必须使用 + 连接起来
如果某些内容想要原样输出,就用""引起来,而要输出变量中的内容,则不要把变量名用""引起来
进制数
(1)十进制:正常表示
System.out.println(10);
(2)二进制:0b或0B开头
System.out.println(0B10);
(3)八进制:0开头
System.out.println(010);
(4)十六进制:0x或0X开头
System.out.println(0X10);
计算机存储单位
-
字节(Byte):是计算机信息技术用于计量存储容量的一种计量单位,一字节等于八位。
-
位(bit):是数据存储的最小单位。也就是二进制。二进制数系统中,每个0或1就是一个位,叫做bit(比特),其中8 bit 就称为一个字节(Byte)。
-
转换关系:
-
8 bit = 1 Byte
-
1024 Byte = 1 KB
-
1024 KB = 1 MB
-
1024 MB = 1 GB
-
1024 GB = 1 TB
-
Java的基本数据类型的存储范围
1、整型系列
(1)byte:字节类型
-
占内存:1个字节
-
存储范围:-128~127
(2)short:短整型类型
-
占内存:2个字节
-
存储范围:-32768~32767
(3)int:整型
-
占内存:4个字节
-
存储范围:-2的31次方 ~ 2的31次方-1
(4)long:整型
-
占内存:8个字节
-
存储范围:-2的63次方 ~ 2的63次方-1
注意:如果要表示某个超过int范围的常量整数它是long类型,那么需要在数字后面加L
2、浮点型系列(小数)
(1)float:单精度浮点型
-
占内存:4个字节
-
精度:科学记数法的小数点后6~7位
注意:如果要表示某个常量小数是float类型,那么需要在数字后面加F或f,否则就是double类型
(2)double:双精度浮点型
-
占内存:8个字节
-
精度:科学记数法的小数点后15~16位
float f = 12.0F;//右边如果赋值小数常量值,那么必须加F或f
3、单字符类型:char
-
占内存:2个字节
4、布尔类型
boolean:只能存储true或false
虽然计算机底层使用0和1表示false和true,但是在代码中不能给boolean类型的变量赋值0和1,只能赋值false和true
基本数据类型转换(Conversion)
在Java程序中,不同的基本数据类型的值经常需要进行相互转换。Java语言所提供的七种数值类型之间可以相互转换,基本数据类型转换有两种转换方式:自动类型转换和强制类型转换。
1、自动类型转换(隐式类型转换)
自动转换:
-
将
取值范围小的类型
自动提升为取值范围大的类型
。
基本数据类型的转换规则
小结:通过上面案例我们可以得出数据类型的转换关系(取值范围从小到大),如图所示:
(1)当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时,
(2)当存储范围小的数据类型与存储范围大的数据类型一起混合运算时,会按照其中最大的类型运算
(3)当byte,short,char数据类型进行算术运算时,按照int类型处理
(4)boolean类型不参与
2、强制类型转换(显示类型转换)
-
强制类型转换:将
取值范围大的类型
强制转换成取值范围小的类型
。
比较而言,自动转换是Java自动执行的,而强制转换需要我们自己手动执行。
转换格式:
数据类型 变量名 = (数据类型)被强转数据值;
(1)当把存储范围大的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围小的变量时,需要强制类型转换,提示:有风险,
(2)boolean类型不参与
(3)当某个值想要提升数据类型时,也可以使用强制类型转换
可能会损失精度或溢出
3、特殊的数据类型转换
1、任意数据类型的数据与String类型进行“+”运算时,结果一定是String类型
2、但是String类型不能通过强制类型()转换,转为其他的类型
小练习
short s1 = 120;
short s2 = 8;
short s3 = s1 + s2;//报错,左边short类型,右边int类型
short s1 = 120;
short s2 = 8;
byte s3 = (byte)(s1 + s2);// s3 = -128 类型强转有风险
char c1 = '0';
char c2 = '1';
char c3 = c1 + c2;//报错,左边char类型,右边int类型
char c1 = '0';
char c2 = '1';
System.out.println(c1 + c2);//int类型直接输出
int i = 4;
long j = 120; //因为右边120默认是int类型,int的值赋值给long类型是可以的,会自动类型转换,但是要求这个int值不能超过int的存储范围,如果超过int的存储范围必须加L.
double d = 34;
float f = 1.2;//因为右边1.2默认是double类型,double的值是不能直接赋值给float的,要么加F要么使用强制类型转换。System.out.println(i + j + d + f);//最后是double
int i = 1;
int j = 2;
double d = i/j;// 右边是int类型,左边是double类型
System.out.println(d);//double类型 0.0
运算符(Operator)
-
表达式:用运算符连接起来的式子
-
运算符的分类: 按照功能分:算术运算符、赋值运算符、比较运算符、逻辑运算、条件运算符...
分类 | 运算符 |
---|---|
算术运算符 | + 、- 、* 、/ 、% 、++ 、-- |
赋值运算符 | = 、+= 、-= 、*= 、/= 、%= 等 |
关系运算符 | > 、>= 、< 、<= 、== 、!= |
逻辑运算符 | & 、| 、^ 、! 、&& 、|| |
条件运算符 | (条件表达式)?结果1:结果2; |
位运算符(了解) | & 、| 、~ 、^ 、<< 、>> 、>>> |
三元运算符,如果内部有未知元,结果按照未知元的类型,其余情况,会按照其中最大的类型运算
算术运算符
算术运算符 | 符号解释 |
---|---|
+ | 加法运算,字符串连接运算,正号 |
- | 减法运算,负号 |
* | 乘法运算 |
/ | 除法运算,整数/整数结果还是整数 |
% | 求余运算,余数的符号只看被除数 |
++ 、 -- | 自增自减运算 |
“+”号的两种用法
第一种:对于
+
两边都是数值的话,+
就是加法的意思第二种:对于
+
两边至少有一边是字符串得话,+
就是拼接的意思
自加自减运算
理解:++
运算,变量自己的值加1。反之,--
运算,变量自己的值减少1,用法与++
一致。
1、单独使用
变量在单独运算的时候,变量
前++
和变量后++
,变量的是一样的;变量
前++
:例如++a
。变量
后++
:例如a++
。
2、复合使用
和
其他变量放在一起使用
或者和输出语句放在一起使用
,前++
和后++
就产生了不同。
变量
前++
:变量先自身加1,然后再取值。变量
后++
:变量先取值,然后再自身加1。
小结:
++在前,先自加,后使用;
++在后,先使用,后自加。
小练习
public static void main(String[] args){
int i = 1;
int j = i++;// i = 1 j = 1 i = 2
// 2 * 2 + (3+1) * 2 = 12
int k = i++ * ++j + ++i * j++;
System.out.println("i = " + i);//4
System.out.println("j = " + j);//3
System.out.println("k = " + k);//12
}
赋值运算符
注意:所有的赋值运算符的=左边一定是一个变量
赋值运算符 | 符号解释 |
---|---|
= | 将符号右边的值,赋值给左边的变量 |
+= | 将符号左边的值 和右边的值 进行相加操作,最后将结果赋值给左边的变量 |
-= | 将符号左边的值 和右边的值 进行相减操作,最后将结果赋值给左边的变量 |
*= | 将符号左边的值 和右边的值 进行相乘操作,最后将结果赋值给左边的变量 |
/= | 将符号左边的值 和右边的值 进行相除操作,最后将结果赋值给左边的变量 |
%= | 将符号左边的值 和右边的值 进行取余操作,最后将结果赋值给左边的变量 |
+=
-=
*=
/=
%=
扩展赋值运算符在将最后的结果赋值给左边的变量前,都做了一步强制类型转换。
关系运算符/比较运算符
关系运算符 | 符号解释 |
---|---|
< | 比较符号左边的数据是否小于右边的数据,如果小于结果是true。 |
> | 比较符号左边的数据是否大于右边的数据,如果大于结果是true。 |
<= | 比较符号左边的数据是否小于或者等于右边的数据,如果大于结果是false。 |
>= | 比较符号左边的数据是否大于或者等于右边的数据,如果小于结果是false。 |
== | 比较符号两边数据是否相等,相等结果是true。 |
!= | 不等于符号 ,如果符号两边的数据不相等,结果是true。 |
比较运算符,是两个数据之间进行比较的运算,运算结果一定是boolean值
true
或者false
。其中>,<,>=,<=不支持boolean,String类型,==和!=支持boolean和String。
逻辑运算符
逻辑运算符,是用来连接两个布尔类型结果的运算符(!
除外),运算结果一定是boolean值true
或者false
逻辑运算符 | 符号解释 | 符号特点 |
---|---|---|
& | 与,且 | 有false 则false |
| | 或 | 有true 则true |
^ | 异或 | 相同为false ,不同为true |
! | 非 | 非false 则true ,非true 则false |
&& | 双与,短路与 | 左边为false,则右边就不看 |
|| | 双或,短路或 | 左边为true,则右边就不看 |
&&和&区别,||和|区别
&&
和&
区别:
&&
和&
结果一样,&&
有短路效果,左边为false,右边不执行;&
左边无论是什么,右边都会执行。
||
和|
区别:
||
和|
结果一样,||
有短路效果,左边为true,右边不执行;|
左边无论是什么,右边都会执行。
条件运算符
条件表达式?结果1:结果2
条件运算符计算方式:
-
条件判断的结果是true,条件运算符整体结果为结果1,赋值给变量。
-
判断条件的结果是false,条件运算符整体结果为结果2,赋值给变量。
位运算符
位运算符 | 符号解释 |
---|---|
& | 按位与,当两位相同时为1时才返回1 |
| | 按位或,只要有一位为1即可返回1 |
~ | 按位非,将操作数的每个位(包括符号位)全部取反 |
^ | 按位异或。当两位相同时返回0,不同时返回1 |
<< | 左移运算符 |
>> | 右移运算符 |
>>> | 无符号右移运算符 |
运算符 | 运算方式 |
---|---|
<< | 空位补0,被移除的高位丢弃,空缺位补0。 |
>> | 当最高位是0,右移后,空缺位补0 当最高位是1,空缺位补1。 |
>>> | 被移位二进制最高位无论是0或者是1,空缺位都用0补。 |
& | 二进制位进行&运算,只有1&1时结果是1,否则是0; |
| | 二进制位进行 | 运算,只有0 | 0时结果是0,否则是1; |
^ | 二进制位相同是0 二进制位不同是1 |
~ | 按补码取反 |
左移:<<
运算规则:左移几位就相当于乘以2的几次方
右移:>>
运算规则:右移几位就相当于除以2的几次方
无符号右移:>>>
运算规则:往右移动后,左边空出来的位直接补0,不看符号位
注意:当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)
byte,short,char在计算时按照int类型处理
如何区分&,|,^是逻辑运算符还是位运算符?
如果操作数是boolean类型,就是逻辑运算符,如果操作数是整数,那么就位运算符
运算符优先级
switch语句
①switch(表达式)中表达式的可选值类型
byte
short
int
char
枚举(JDK1.5)
String(JDK1.7)
②case子句
-
case子句中指定的值必须是常量,不能是变量或不确定的表达式的值
-
同一个switch语句中所有case子句中的常量值必须互不相同
③default子句
-
default子句是可选的
-
default子句的位置是灵活的
注意:如果case或default语句后没有加break,会依次再向下执行,直至完结或者break
IDEA常用快捷键
按键 | 功能 |
---|---|
psvm | 生成main方法 |
sout | 生成System.out.println(); |
soutp | 生成对方法参数的打印 |
soutv | 生成对前面已声明变量的打印 |
fori | 生成带循环变量的for循环结构 |
ifn | 生成判断某个变量是否为null的if语句 |
inn | 生成判断某个变量是否非null的if语句 |
Ctrl+Alt+l | 格式化代码 |
Ctrl+d | 复制行 |
Ctrl+x | 剪切行 |
Ctrl+v | 粘贴 |
Ctrl+y | 删除行 |
Ctrl+/ | 添加或去除单行注释 |
shift+F6 | 重命名类或变量 |
shift+Alt+↑ | 向上移动当前行代码 |
shift+Alt+↓ | 向下移动当前行代码 |
shift+enter | 即使光标在行的中间,也能直接去下一行开始继续输入 |
Ctrl+n | 搜索类 |
Ctrl+F12 | 显示类的成员 |
Ctrl+shift+U | 切换大小写 |
数组
①概念
一组相同类型数据的容器。
-
相同类型:Java语言要求存入数组的数据类型必须一致
-
容器:类似于生活中存放物品的容器,在编程的世界中,『容器』可以用来存放数据
-
一组:容器中可以存放多个数据
②声明数组变量
int[] ageArray;
String[] nameArray;
double salaryArray [];
③创建数组对象
[1]动态创建数组
ageArray = new int[5];
[2]静态创建数组
此时[]中不能写数字指定长度
nameArray = new String[]{"foo", "bar", "biz"};
int[] numberArray = {5, 7, 11, 13, 17, 19};
④ 数组中元素默认值
系统创建数组对象后,必须分配和数组长度匹配的空间,此时每一个数组元素都会被系统分配默认值。
引用类型不管是成员变量、类变量还是局部变量都有初始值
内存分析
①声明基本数据类型变量
int a = 10;//直接在栈区创建
②创建对象
Scanner scanner = new Scanner(System.in); //栈区创建对象引用,堆内存创建对象并指向
③创建数组对象
多维数组
创建对象
[1]创建二维数组格式一
int[][] arr2d01 = new int[3][2];
[2]创建二维数组格式二
int[][] arr2d02 = new int[3][];//动态初始化——仅指定第一个维度的数组长度
// Java中多维数组不必都是规则矩阵形式
arr2d02[0] = new int[]{3, 5, 7};
arr2d02[1] = new int[]{14, 21, 66, 89};
arr2d02[2] = new int[]{90, 100};
[3]创建二维数组格式三
// 静态初始化——在创建对象时将数据填充
// 此时如果某个元素位置设置为null不会编译报错,但是访问这个位置时还是要先初始化
int[][] arr2d03 = new int[][]{{1,2,3}, {4,5}, null, {6,7,8}};// 前面设置null的地方,需要初始化才可以访问
arr2d03[2] = new int[]{12,24};
arr2d03[2][0] = 5;
[4]创建二维数组格式四
int[] x[] = new int[][]{{1,2,3}, {4,5}, {6,7,8}};
访问数据
访问二维数组元素
// 二、访问二维数组元素(读、写)
int[][] arr2d05 = new int[2][2];// 向数组元素写入数据
arr2d05[1][0] = 10;// 读取数组元素
System.out.println("arr2d05[1][0] = " + arr2d05[1][0]);
遍历数组
int[][] arr2d06 = new int[][]{{1,2,3},{4,5,6},{7,8,9}};
// 先遍历第一个维度:取出每一个一维数组
for (int i = 0; i < arr2d06.length; i++) {int[] intArr = arr2d06[i];
for (int j = 0; j < intArr.length; j++) {
int intValue = intArr[j];
System.out.println("intValue["+i+"]["+j+"] = " + intValue);
}}
小练习
//杨辉三角形 public static void main(String[] args) { Scanner sc = new Scanner(System.in); int n = sc.nextInt();//层数 int[][] yanghuiArr = new int[n][n*2]; yanghuiArr[0][n] = 1; for(int i = 1; i < n;i++){ for(int j = 0;j<2*n;j++){ if(j == 0){ yanghuiArr[i][j] = 0; } else{ if(j != 2*n-1) yanghuiArr[i][j] = yanghuiArr[i-1][j-1]+yanghuiArr[i-1][j+1]; } } } yanghuiArr[n-1][2*n-1] = 1; for(int i = 0;i<n;i++){ for(int j =0;j<2*n;j++){ if(yanghuiArr[i][j] == 0){ System.out.print("\t"); }else{ System.out.print(yanghuiArr[i][j]+"\t"); } } System.out.println(); } }