文章目录
第一章 Java概述
1.1 Java是什么
Java是一门面向对象的编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概念,因此Java语言具有功能强大和简单易用两个特征。Java语言作为静态面向对象编程语言的代表,极好地实现了面向对象理论,允许程序员以优雅的思维方式进行复杂的编程。
Java具有简单性、面向对象、分布式、健壮性、安全性、平台独立与可移植性、多线程、动态性等特点。Java可以编写桌面应用程序、Web应用程序、分布式系统和嵌入式系统应用程序等。
1.2 Java语言的特点
(1)优点
- 面向对象:Java语言支持封装、继承、多态,面向对象编程,让程序更好达到
高内聚
,低耦合
的标准。 - 支持分布式:Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。
- 健壮型:Java的强类型机制、异常处理、垃圾的自动收集等是Java程序健壮性的重要保证。对指针的丢弃是Java的明智选择。
- 安全性高:Java通常被用在网络环境中,为此,Java提供了一个安全机制以防恶意代码的攻击。如:安全防范机制(类ClassLoader),如分配不同的名字空间以防替代本地的同名类、字节代码检查。
- **跨平台性:**Java程序(后缀为java的文件)在Java平台上被编译为体系结构中立的字节码格式(后缀为class的文件),然后可以在实现这个Java平台的任何系统中运行。
(2)缺点
- 语法过于复杂,严谨,对程序员的约束比较多,与python和php等相比入门相对较难。但是一旦学会了,就业岗位需求量大,而且薪资待遇节节攀升。
- 一般适用于大型网站开发,整个架构会比较重,对于初创公司开发和维护人员的成本比较高(即薪资高),选择用Java语言开发网站或应用系统的需要一定的经济实力。
1.3 Java语言的跨平台原理
很多时候,我们写的程序可能要在多个操作系统运行,这个时候就要求我们的程序需要在尽可能不改动的情况下完实现这个目标。不同的语言实现跨平台的方式不同。Java语言实现跨平台是建立在“虚拟机”基础之上的。
Java设计了一套简洁的虚拟指令集,也就是字节码。如果我们想要在一台机器上运行Java程序,只需要将Java程序编译成字节码就可以了。编写一个将Java程序翻译成Java字节码的编译器。可是这里产生了一个问题,难道我们的机器可以直接执行字节码这样的虚拟指令集吗?当然是不能的。我们需要针对不同的指令集,开发对应的字节码解释器。这个工作同样比较简单,实现了**“一处编译,到处运行”**的效果。
Java虚拟机(JVM,Java Virtual Machine)是由软件技术模拟出计算机运行的一个虚拟的计算机,它负责解释执行字节码指令集。也就是说,只要一台机器可以运行Java的虚拟机,那么就能运行Java语言编写的程序。而不同的平台,需要安装不同的Java虚拟机程序。那么我们编写完Java程序之后,需要先将.java的源文件编译为.class的字节码文件,然后在Java虚拟机中来执行这些字节码文件。
1.4 JVM、JRE、JDK的关系
- JVM(Java Virtual Machine ):Java虚拟机,是运行所有Java程序的假想计算机,是Java程序的运行环境之一,也是Java 最具吸引力的特性之一。我们编写的Java代码,都运行在JVM 之上。
- JRE (Java Runtime Environment) :是Java程序的运行时环境,包含
JVM
和运行时所需要的核心类库
。 - JDK (Java Development’s Kit):是Java程序开发工具包,包含
JRE
和开发人员使用的工具。
想要运行一个已有的Java程序,那么只需安装
JRE
即可。
想要开发一个全新的Java程序,那么必须安装JDK
,其内部包含JRE
。
JDK、JRE和JVM的关系:
JDK = JRE + 开发工具集(编译工具、打包工具等)
JRE = JVM + Java SE标准类库
1.5 JDK的下载
-
下载网址:www.oracle.com
-
下载步骤:
-
登录Oracle公司官网,www.oracle.com,如图所示:在底部选择Developers开发者
-
在Developers页面中间的技术分类部分,选择
Java
,单击进入,如图所示:
-
单击Download Java,然后选择具体的版本下载。
-
-
选择Java 8 Windows版,然后再选择64为进行下载
1.6 安装JDK
- 下载成功后,双击
jdk-8u202-windows-x64.exe
文件,并单击下一步
-
下一步
-
选择安装的目录
-
完成
安装后的文件目录
配置环境变量
找到设置,点击关于—>高级系统设置----->环境变量
- 系统变量----->新建
JAVA_HOME : C:\Program Files\Java\jdk1.8.0_144
- PATH -----> 编辑
-
新建---->
%JAVA_HOME%\bin
-----> 确定
-
配置完成后在dos窗口输入
javac
、java
出现下面的结果说明环境已经配置完成了
1.7 入门程序HelloWorld
Java程序开发三步骤:编写、编译、运行。
- 创建一个文本文件,将文件后缀名改为
.java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("HelloWorld");
}
}
- 写入代码,保存文件,在当前文件路径打开dos窗口
javac HelloWorld.java
编译java文件java HelloWorld
执行.class文件
第二章 Java基础语法
2.1 注释
注释是对代码进行解释说明的,其目的是为了让人们能够更好的了解代码。在Java中存在三种注释:
- 单行注释:单行注释以
//
开头,换行结束
// 单行注释
- 多行注释:多行注释以
/*
开头,以*/
结束
/*
多行注释
*/
- 文档注释:文档注释以
/**
开头,以*/
结束
/**
* 文档注释
*/
2.2 关键字
关键字是指在Java语言中被赋予特定含义的单词
关键字的特点:组成关键字的英文字母全是小写
我们在之前所用的的关键字有:public 、class 、static 、void
在Java中一共存在50个关键字,其中const
和 goto
是保留字,目前并不使用
2.3 标识符
标识符:给类、变量、方法、包等命名的字符序列称为标识符
标识符命名规则:
- 必须是以字母、数字、下划线和$组成
- 字母包括大写和小写
- 数字0-9
- 下划线 _
- 美元符号 $
- Java关键字不能作为标识符
- 不能以数字开头
- 严格区分大小写
标识符的命名规范:
-
采用驼峰命名法,做到见名知意
-
包名:每一个单词都小写,单词之间用.做分割,形式:xxx.yyy.zzz
-
类名、接口名:每个单词的首字母都大写,形如:XxxYyyZzz
-
方法名、变量名:从第二个单词开始首字母大写,其余字母小写,形如:xxxYyyZzz
-
常量名:每一个字母都大写,单词之间用下划线分割,形如:XXX_YYY_ZZZ
2.4 常量值
常量:在程序执行过程中其值不能发生改变
常量值分为字面值常量
和自定义常量
(面向对象部分)
字面值常量的分类:
输出不同的常量值:
public class ConstantDemo {
public static void main(String[] args) {
// 整数型常量
System.out.println(12);
System.out.println(-123);
// 浮点数型常量
System.out.println(3.14f);
System.out.println(3.14159);
// 字符型常量
System.out.println('a');
System.out.println('中');
// 字符串型常量
System.out.println("HelloWorld");
System.out.println("我爱你中国");
// 布尔型常量
System.out.println(true);
System.out.println(false);
}
}
转义字符定义:在字符常量中,反斜杠\是一个特殊的字符,被称为转义字符
当要输出一些特殊的字符时需要使用到转义字符
常见的转义字符:
- \r:表示回车符,会将\r后面的内容定位到当前行的开头,覆盖等量的字符且不会跳到下一行
- \n:表示换行符
- \t:表示制表符
- \b:表示退格键
public class TransTest {
public static void main(String[] args) {
System.out.println("HelloJava");
System.out.println("Hello\rJava");
System.out.println("Hello\rJava111");
System.out.println("Hello\nJava");
System.out.println("Hello\tJava");
System.out.println("Hello\bJava");
System.out.println("\"");
System.out.println("\\");
}
}
2.5 计算机中的数据存储
2.5.1 计算机存储单位
-
字节(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
2.5.2 进制
进制就是进位制,是人们规定的一种进位方法。 对于任何一种进制–X进制,就表示某一位置上的数运算时是逢X进一位。二进制就是逢二进一,八进制是逢八进一,十进制是逢十进一,十六进制是逢十六进一。例如一周有七天,七进制,一年有十二个月,十二进制
进制的分类:
-
十进制:
数字组成:0-9
整数默认就是十进制 -
二进制:
数字组成:0-1
表现形式:以0b开头(b可大写可小写) -
八进制:很少使用(将二进制中的三位用一位表示)
数字组成:0-7
表现形式:以0开头 -
十六进制(将二进制中的四位用一位表示)
数字组成:0-9,a-f
表现形式:以0x开头(x可大写可小写)
使用不同进制输出100
public class ScaleTest {
public static void main(String[] args) {
// 二进制的100
System.out.println(0b100);
// 八进制的100
System.out.println(0100);
// 十进制的100
System.out.println(100);
// 十六进制的100
System.out.println(0x100);
}
}
2.6 变量
2.6.1 变量的概念
变量:在程序执行过程中,值可以发生改变的量。
Java变量是程序中最基本的存储单元,其要素包括变量类型
、变量名
和变量值
从本质上来讲,变量其实是内存中的一小块区域,使用变量名来访问这块区域,因此,每一个变量使用前,必须要先申请(声明),然后必须进行赋值(填充内容),才能使用
2.6.2 变量定义的方式
方式一:数据类型 变量名 = 变量值;
方式二:数据类型 变量名 ;
变量名 = 变量值;
public class VariateTest {
public static void main(String[] args) {
int num = 5 ;
int temp ;
temp = 8 ;
System.out.println(num);
System.out.println(temp);
}
}
数据类型
- 变量的数据类型决定了在内存中开辟多大空间
- 变量的数据类型也决定了该变量可以存什么值
变量名
- 见名知意非常重要
值
- 基本数据类型的变量:存储数据值
- 引用数据类型的变量:存储地址值,即对象的首地址。例如:String类型的变量存储的是字符串对象的首地址
2.6.3变量的使用步骤
- 声明:在内存中申请空间
- 赋值(初始化):把值赋到对应的内存空间
- 使用
2.6.5 最终变量
使用final关键字修饰的变量称为最终变量,也就是常量,加final修饰后,这个变量的值就不能修改了
public class FinalTest {
public static void main(String[] args) {
final int NUM = 5 ;
System.out.println(NUM);
NUM = 8 ;
}
}
2.7 Java中的数据类型
数据类型的作用:Java是一种强类型语言,对于每一种数据都明确定义了具体的数据类型,在内存中分配了不同大小的内存空间。
Java中数据类型分为基本数据类型
和引用数据类型
2.7.1 基本数据类型
-
整数型
对于整数型中的long,推荐在其值后加上l或L来标识 -
浮点型
float为单精度浮点型,其精度为科学记数法的小数点后6~7位
double为双精度浮点型,其精度为科学记数法的小数点后15~16位
在定义float类型时候,必须在float类型的值后面加特殊的标识(f或者F,一般使用f)
- 字符型
-
布尔型
在计算机底层使用1表示true,0表示false -
各种基本数据类型的默认值
2.7.2 基本数据类型转换
在Java程序中,不同的基本数据类型的值经常需要进行相互转换。Java语言所提供的七种数值类型之间可以相互转换,基本数据类型转换有两种转换方式:自动类型转换和强制类型转换。
boolean类型不参与。
- 自动类型转换(隐式类型转换)
将
取值范围小的类型
自动提升为取值范围大的类型
Java中的默认转换规则
- byte short char 运算过程中 自动提升为 int
- 取值范围小的数据类型与取值范围大的数据类型进行运算,会先将小的数据类型提升为其中最大的类型,再运算。
基本数据类型的转换规则如图所示:
public class TypeConverTest {
public static void main(String[] args) {
int x = 10 ;
byte b = 4 ;
short s = 7 ;
long l = 100L ;
x = x + b ; // 将byte类型的b自动转换为int类型然后进行运算
System.out.println(x);
x = x + s ; // 将short类型的s自动转换为int类型然后进行运算
System.out.println(x);
l = x + l ; // 将int类型的x自动转换为long类型然后进行运算
System.out.println(l);
}
}
- 当byte,short,char数据类型进行算术运算时,按照int类型处理
byte b1 = 1;
byte b2 = 2;
byte b3 = b1 + b2;//编译报错,b1 + b2自动升级为int
char c1 = '0';
char c2 = 'A';
System.out.println(c1 + c2);//113
- 当把存储范围小的值(常量值、变量的值、表达式计算的结果值)赋值给了存储范围大的变量时。
int i = 'A';//char自动升级为int,其实就是把字符的编码值赋值给i变量了
double d = 10;//int自动升级为double
byte b = 127; //右边的整数常量值必须在-128~127范围内
//byte bigB = 130;//错误,右边的整数常量值超过byte范围
long bigNum = 12345678912L;//右边的整数常量值如果超过int范围,必须加L,否则编译不通过
- 当存储范围小的数据类型与存储范围大的数据类型一起混合运算时,会按照其中最大的类型运算。
int i = 1;
byte b = 1;
double d = 1.0;
double sum = i + b + d;//混合运算,升级为double
- 强制类型转换(显示类型转换)
public class TypeConverTest1 {
public static void main(String[] args) {
int a = 10 ;
byte b = 5 ;
b = a + b ;
}
}
int型和byte型相加结果赋值给byte型变量,需要使用到强制类型转换
强制类型转换格式:目标类型 变量名 = (目标类型)(被转换的数据);
public class TypeConverTest1 {
public static void main(String[] args) {
int a = 10 ;
byte b = 5 ;
b = (byte)(a + b) ; //强制类型转换
}
}
需要注意的事项:如果超出了被赋值的数据类型的取值范围得到的结果会与你期望的结果不同。
如:byte b = (byte)(127 + 1);
public class TypeConverTest1 {
public static void main(String[] args) {
byte b = (byte)(127 + 1) ;
System.out.println(b);
}
}
如:int i = (int)3.14;
public class TypeConverTest1 {
public static void main(String[] args) {
int i = (int)3.14 ;
System.out.println(i);
}
}
当某个值想要提升数据类型时,也可以使用强制类型转换
public class TypeConverTest1 {
public static void main(String[] args) {
int i = 1;
int j = 2;
double d = (double)i/j;
System.out.println(d);
}
}
2.8 运算符和标点符号
2.8.1 运算符的分类
2.8.2 算术运算符
示例:
public class OperatorTest {
public static void main(String[] args) {
int a = 3;
int b = 4;
System.out.println(a + b);
System.out.println(a - b);
System.out.println(a * b);
System.out.println(a / b);
System.out.println(a % b);
System.out.println(5%2);//1
System.out.println(5%-2);//1
System.out.println(-5%2);//-1
System.out.println(-5%-2);//-1
}
}
-
“+”的两种用法
- 第一种:对于+两边都是数值的话,+就是加法的意思 - 第二种:对于+两边至少有一边是字符串得话,+就是拼接的意思
public class AddTest {
public static void main(String[] args) {
int a = 5 ;
int b = 10 ;
String str1 = "HelloWorld" ;
String str2 = "Java" ;
// 两数相加
System.out.println(a + b);
// 两字符串拼接
System.out.println(str1 = str2);
// 数字和字符串相加,表示拼接
System.out.println(a + str1);
}
}
- 自加自减运算
++:自加。对原有的数据进行+1
–:自减。对原有的数据进行-1
单独使用时,变量前++和变量后++,变量的是一样的,如++a 和 a++
参与运算时,++放在操作数的前面,是先自增然后再参加运算;++放在操作数的后面是先参与运算再自增
public class Test3 {
public static void main(String[] args) {
int a = 5 ;
int b = 5 ;
int num , temp;
// 参与运算
num = a++ ;
temp = ++b ;
System.out.println(num);
System.out.println(temp);
}
}
2.8.3 赋值运算符
- 基本赋值运算符
=
把=右边的数据赋值给左边变量
- 扩展赋值运算符
+=,-=,*=,/=,%=
把左边和右边做对应运算,然后赋值给左边。
扩展赋值运算符示例:
public class Test4 {
public static void main(String[] args) {
int a = 10 ;
int b = 5 ;
int c = 6 ;
int d = 2 ;
int e = 8 ;
// +=
a += 1 ;
System.out.println(a);
// -=
b -= 1 ;
System.out.println(b);
// *=
c *= 2 ;
System.out.println(c);
// /=
d /= 2 ;
System.out.println(d);
// %=
e %= 3 ;
System.out.println(e);
}
}
short s=1;
s = s+1; //2
short s=1;
s+=1;//2
short s=1;
s = s+1; // 会报错
// 当short与int进行运算的时候,会提升为int类型,两个int类型相加的结果也是int类型
short s=1;
s+=1; // 不报错
//s = (short)(s + 1); += 隐含了强制类型转换
2.8.4 关系运算符/比较运算符
返回值一定是布尔类型 (true false)
class Test5 {
public static void main(String[] args) {
//==,!=,>,>=,<,<=
System.out.println(4 == 3);
System.out.println(4 != 3);
System.out.println(4 > 4);
System.out.println(4 >= 4);
System.out.println(4 < 3);
System.out.println(4 <= 3);
}
}
2.8.4 逻辑运算符
用来连接两个布尔类型值的运算符(!
除外),最终结果一定是boolean值(true
false
)
&逻辑与:有false则false,如果需要返回true,要求符号两边都是true。
|逻辑或:有true则true,如果需要返回true,只要符号一边是true即可。
^逻辑异或:相同为false,不同为true。
!逻辑非:非false则true,非true则false。 特点:偶数个不改变本身。
- 逻辑运算符&&和&区别
逻辑返回值最终结果一样。
&&具有短路效果。左边是false,右边不执行。
&是无论左边是false还是true,右边都会执行。
- 逻辑运算符||和|区别
逻辑返回值最终结果一样
||具有短路效果。左边是true,右边不执行
|是无论左边是false还是true,右边都会执行
2.8.5 三元运算符
格式:数据类型 变量 = 条件表达式?结果1:结果2;
- 三元运算符的执行流程
先执行条件表达式,依据此返回值决定赋值结果
如果条件为true,运算后的结果是将值1赋值给变量;
如果条件为false,运算后的结果是将值2赋值给变
示例:获取两个数中的最大值
public class Test6 {
public static void main(String[] args) {
int x = 10 ;
int y = 15 ;
int z ;
z = (x > y) ? x : y ;
System.out.println(z);
}
}
2.8.6 位运算符
-
位运算符的运算过程都是基于补码运算,但是看结果,我们得换成原码,再换成十进制看结果
-
正数的原码反码补码都一样,负数原码反码补码不一样
-
byte,short,char在计算时按照int类型处理
如何区分&,|,^是逻辑运算符还是位运算符?
如果操作数是boolean类型,就是逻辑运算符,如果操作数是整数,那么就位运算符。
-
原码
就是二进制定点表示法,即最高位为符号位,“0”表示正,“1”表示负,其余位表示数值的大小。
通过一个字节,也就是8个二进制位表示+7
和-7
00000111
10000111
-
反码
正数的反码与其原码相同;负数的反码是对其原码逐位取反,但符号位除外。
00000111
的反码还是00000111
10000111
的反码是11111000
-
补码
-
正数的补码与其原码相同;负数的补码是在其反码的末位加1。
00000111
的反码、补码
反码00000111
补码00000111
10000111
的反码、补码
反码11111000
补码11111001
正数的源码、反码、补码都相同。
负数的反码是源码取反(符号位除外)、补码是反码末位+1.
负数的原码到补码,补码到原码
从右侧第一个1开始找,右侧的内容不变,左侧的内容除符号位不变,其余位,0变1,1变0。
(1)左移:<<
运算规则:左移几位就相当于乘以2的几次方
注意:当左移的位数n超过该数据类型的总位数时,相当于左移(n-总位数)位
byte,short,char
在计算时按照int类型处理
System.out.println(3<<4); // 3*2*2*2*2
System.out.println(-3<<4); // -3*2*2*2*2
(2)右移:>>
快速运算:类似于除以2的n次,如果不能整除,向下取整
System.out.println(69>>4); // 69/2/2/2/2
System.out.println(-69>>4); // -69/2/2/2/2
(3)无符号右移:>>>
运算规则:往右移动后,左边空出来的位直接补0,不看符号位
正数:和右移一样
负数:右边移出去几位,左边补几个0,结果变为正数
System.out.println(69 >>> 4); // 69/2/2/2/2
System.out.println(-69 >>> 4); // 268435451
(4)按位与:&
运算规则:对应位都是1才为1
1 & 1 结果为1
1 & 0 结果为0
0 & 1 结果为0
0 & 0 结果为0
System.out.println(9 & 7); // 1
System.out.println(-9 & 7); // 7
(5)按位或:|
运算规则:对应位只要有1即为1
1 | 1 结果为1
1 | 0 结果为1
0 | 1 结果为1
0 & 0 结果为0
System.out.println(9 | 7); // 15
System.out.println(-9 | 7); // -9
(6)按位异或:^
运算规则:对应位一个为1一个为0,才为1
1 ^ 1 结果为0
1 ^ 0 结果为1
0 ^ 1 结果为1
0 ^ 0 结果为0
System.out.println(9 ^ 7); // 14
System.out.println(-9 ^ 7); // -16
(7)按位取反:
~运算规则:~0就是1 ~1就是0
System.out.println(~9); // -10
System.out.println(~-9); // 8
2.8.7 运算符优先级
2.8.8 标点符号
- 小括号()用于强制类型转换、表示优先运算表达式、方法参数列表
-
大括号{}用于数组元素列表、类体、方法体、复合语句代码块边界符
-
中括号[]用于数组
-
分号;用于结束语句
-
逗号,用于多个赋值表达式的分隔符和方法参数列表分隔符
-
英文句号.用于成员访问和包目录结构分隔符
-
英文省略号…用于可变参数
-
@用于注解
-
双冒号::用于方法引用