# Java 概述

# Java 语言跨平台原理

Java 程序并非是直接运行的,Java 编译器将 Java 源程序编译成与平台无关的字节码文件 (class 文件),然后由 Java 虚拟机(JVM)对字节码文件解释执行。所以在不同的操作系统下,只需安装不同的 Java 虚拟机即可实现 java 程序的跨平台。

# JRE 和 JDK

JVM(Java Virtual Machine),Java 虚拟机
JRE(Java Runtime Environment),Java 运行环境,包含了 JVM 和 Java 的核心类库(Java API)
JDK(Java Development Kit)称为 Java 开发工具,包含了 JRE 和开发工具
总结:我们只需安装 JDK 即可,它包含了 java 的运行环境和虚拟机。

# JDK 的下载和安装(应用)

通过官方网站获取 JDK
http://www.oracle.com
注意:安装路径不要包含中文或者空格等特殊字符(使用纯英文目录)。

# JDK 的安装目录介绍

目录名称说明
bin该路径下存放了 JDK 的各种工具命令。javac 和 java 就放在这个目录。
conf该路径下存放了 JDK 的相关配置文件。
include该路径下存放了一些平台特定的头文件。
jmods该路径下存放了 JDK 的各种模块。
legal该路径下存放了 JDK 各模块的授权文档。
lib该路径下存放了 JDK 工具的一些补充 JAR 包。

# 第一个演示程序

# 常用 DOS 命令

在接触集成开发环境之前,我们需要使用命令行窗口对 java 程序进行编译和运行,所以需要知道一些常用 DOS 命令。

1、打开命令行窗口的方式:win + r 打开运行窗口,输入 cmd,回车。
2、常用命令及其作用

操作说明
盘符名称:盘符切换。E: 回车,表示切换到 E 盘。
dir查看当前路径下的内容。
cd 目录进入单级目录。cd itheima
cd ..回退到上一级目录。
cd 目录 1\ 目录 2...进入多级目录。cd itheima\JavaSE
cd \回退到盘符目录。
cls清屏。
exit退出命令提示符窗口。

# Path 环境变量的配置

我们不可能把所有的 java 文件都放到 JDK 的 bin 目录下,所以配置环境变量的作用就是可以使 bin 目录下的 java 相关命令可以在任意目录下使用。

# HelloWorld 案例的编写

编写程序,编译程序,运行程序。

public class HelloWorld {
	public static void main(String[] args) {
		System.out.println("HelloWorld");
	}
}

# HelloWorld 案例的编译和运行

存文件,打开命令行窗口,将目录切换至 java 文件所在目录,编译 java 文件生成 class 文件,运行 class 文件。

编译:javac 文件名.java

范例:javac HelloWorld.java

执行:java 类名

范例:java HelloWorld

# HelloWorld 案例常见问题

# BUG

在电脑系统或程序中,隐藏着的一些未被发现的缺陷或问题统称为 bug(漏洞)。

# HelloWorld 案例常见问题

1、非法字符问题。Java 中的符号都是英文格式的。

2、大小写问题。Java 语言对大小写敏感(区分大小写)。

3、在系统中显示文件的扩展名,避免出现 HelloWorld.java.txt 文件。

4、编译命令后的 java 文件名需要带文件后缀.java

5、运行命令后的 class 文件名(类名)不带文件后缀.class

...

# java 基础语法

# 注释

// 这是单行注释文字
/*
这是多行注释文字
这是多行注释文字
*/
注意:多行注释不能嵌套使用。

文档注释。文档注释以 /** 开始,以 */ 结束。

# 关键字

关键字是指被 java 语言赋予了特殊含义的单词。

关键字的特点:

​ 关键字的字母全部小写。

​ 常用的代码编辑器对关键字都有高亮显示,比如现在我们能看到的 public、class、static 等。

# 常量

常量:在程序运行过程中,其值不可以发生改变的量。

Java 中的常量分类:

​ 字符串常量 用双引号括起来的多个字符(可以包含 0 个、一个或多个),例如 "a"、"abc"、"中国" 等

​ 整数常量 整数,例如:-10、0、88 等

​ 小数常量 小数,例如:-5.5、1.0、88.88 等

​ 字符常量 用单引号括起来的一个字符,例如:'a'、'5'、'B'、' 中 ' 等

​ 布尔常量 布尔值,表示真假,只有两个值 true 和 false

​ 空常量 一个特殊的值,空值,值为 null

除空常量外,其他常量均可使用输出语句直接输出。

public class Demo {
    public static void main(String[] args) {
        System.out.println(10); // 输出一个整数
        System.out.println(5.5); // 输出一个小数
        System.out.println('a'); // 输出一个字符
        System.out.println(true); // 输出 boolean 值 true
        System.out.println("欢迎来到黑马程序员"); // 输出字符串
    }
}

# 数据类型

# 计算机存储单元

  1. 我们知道计算机是可以用来存储数据的,但是无论是内存还是硬盘,计算机存储设备的最小信息单元叫 “位(bit)”,我们又称之为 “比特位”,通常用小写的字母”b” 表示。而计算机中最基本的存储单元叫 “字节(byte)”,
  2. 通常用大写字母”B” 表示,字节是由连续的 8 个位组成。
  3. 除了字节外还有一些常用的存储单位,其换算单位如下:
  • 1B(字节) = 8bit

  • 1KB = 1024B

  • 1MB = 1024KB

  • 1GB = 1024MB

  • 1TB = 1024GB

# Java 中的数据类型

Java 是一个强类型语言,Java 中的数据必须明确数据类型。在 Java 中的数据类型包括基本数据类型和引用数据类型两种。

Java 中的基本数据类型:

数据类型关键字内存占用取值范围
整数类型byte1-128~127
short2-32768~32767
int (默认)4-2 的 31 次方到 2 的 31 次方 - 1
long8-2 的 63 次方到 2 的 63 次方 - 1
浮点类型float4负数:-3.402823E+38 到 - 1.401298E-45 正数: 1.401298E-45 到 3.402823E+38
double (默认)8负数:-1.797693E+308 到 - 4.9000000E-324 正数:4.9000000E-324 到 1.797693E+308
字符类型char20-65535
布尔类型boolean1true,false

说明:

​ 1. e+38 表示是乘以 10 的 38 次方,同样,e-45 表示乘以 10 的负 45 次方。

​ 2. 在 java 中整数默认是 int 类型,浮点数默认是 double 类型。

# 变量的定义

int a = 10, b = 20; // 定义 int 类型的变量 a 和 b,中间使用逗号隔开
System.out.println(a);
System.out.println(b);
int c,d; // 声明 int 类型的变量 c 和 d,中间使用逗号隔开
c = 30;
d = 40;
System.out.println(c);
System.out.println(d);

# 使用变量时的注意事项

  1. 在同一对花括号中,变量名不能重复。
  2. 变量在使用之前,必须初始化(赋值)。

定义 long 类型的变量时,需要在整数的后面加 L(大小写均可,建议大写)。因为整数默认是 int 类型,整数太大可能超出 int 范围。

定义 float 类型的变量时,需要在小数的后面加 F(大小写均可,建议大写)。因为浮点数的默认类型是 double, double 的取值范围是大于 float 的,类型不兼容。

# 标识符

标识符是用户编程时使用的名字,用于给类、方法、变量、常量等命名。

Java 中标识符的组成规则:

  1. 由字母、数字、下划线 “_”、美元符号 “$” 组成,第一个字符不能是数字。
  2. 不能使用 java 中的关键字作为标识符。
  3. 标识符对大小写敏感(区分大小写)。

Java 中标识符的命名约定:

​ 小驼峰式命名:变量名、方法名

​ 首字母小写,从第二个单词开始每个单词的首字母大写。

​ 大驼峰式命名:类名

​ 每个单词的首字母都大写。

​ 另外,标识符的命名最好可以做到见名知意

​ 例如:username、studentNumber 等。

# 类型转换

在 Java 中,一些数据类型之间是可以相互转换的。分为两种情况:自动类型转换和强制类型转换。

自动类型转换:

​ 把一个表示数据范围小的数值或者变量赋值给另一个表示数据范围大的变量。这种转换方式是自动的,直接书写即可。例如:

double num = 10; // 将 int 类型的 10 直接赋值给 double 类型
System.out.println(num); // 输出 10.0

强制类型转换:

​ 把一个表示数据范围大的数值或者变量赋值给另一个表示数据范围小的变量。

​ 强制类型转换格式:目标数据类型 变量名 = (目标数据类型) 值或者变量;

​ 例如:

double num1 = 5.5;
int num2 = (int) num1; // 将 double 类型的 num1 强制转换为 int 类型
System.out.println(num2); // 输出 5(小数位直接舍弃)

1543196882672

说明:

  1. char 类型的数据转换为 int 类型是按照码表中对应的 int 值进行计算的。比如在 ASCII 码表中,'a' 对应 97。
int a = 'a';
System.out.println(a); // 将输出 97
  1. 整数默认是 int 类型,byte、short 和 char 类型数据参与运算均会自动转换为 int 类型。
byte b1 = 10;
byte b2 = 20;
byte b3 = b1 + b2; 
// 第三行代码会报错,b1 和 b2 会自动转换为 int 类型,计算结果为 int,int 赋值给 byte 需要强制类型转换。
// 修改为:
int num = b1 + b2;
// 或者:
byte b3 = (byte) (b1 + b2);
  1. boolean 类型不能与其他基本数据类型相互转换。

# 运算符

# 算术运算符

int a = 10;
int b = 20;
int c = a + b;

+:是运算符,并且是算术运算符。

a + b:是表达式,由于 + 是算术运算符,所以这个表达式叫算术表达式。

符号作用说明
+参看小学一年级
-参看小学一年级
*参看小学二年级,与 “×” 相同
/参看小学二年级,与 “÷” 相同
%取余获取的是两个数据做除法的余数

注意:

/ 和 % 的区别:两个数据做除法,/ 取结果的商,% 取结果的余数。

整数操作只能得到整数,要想得到小数,必须有浮点数参与运算。

int a = 10;
int b = 3;
System.out.println(a / b); // 输出结果 3
System.out.println(a % b); // 输出结果 1

# 字符的 “+” 操作

char 类型参与算术运算,使用的是计算机底层对应的十进制数值。需要我们记住三个字符对应的数值:
'a' -- 97 a-z 是连续的,所以 'b' 对应的数值是 98,'c' 是 99,依次递加
'A' -- 65 A-Z 是连续的,所以 'B' 对应的数值是 66,'C' 是 67,依次递加
'0' -- 48 0-9 是连续的,所以 '1' 对应的数值是 49,'2' 是 50,依次递加

// 可以通过使用字符与整数做算术运算,得出字符对应的数值是多少
char ch1 = 'a';
System.out.println(ch1 + 1); // 输出 98,97 + 1 = 98
char ch2 = 'A';
System.out.println(ch2 + 1); // 输出 66,65 + 1 = 66
char ch3 = '0';
System.out.println(ch3 + 1); // 输出 49,48 + 1 = 49

算术表达式中包含不同的基本数据类型的值的时候,整个算术表达式的类型会自动进行提升。

byte 类型,short 类型和 char 类型将被提升到 int 类型,不管是否有其他类型参与运算。
整个表达式的类型自动提升到与表达式中最高等级的操作数相同的类型

   等级顺序:byte,short,char --> int --> long --> float --> double
byte b1 = 10;
byte b2 = 20;
//byte b3 = b1 + b2; // 该行报错,因为 byte 类型参与算术运算会自动提示为 int,int 赋值给 byte 可能损失精度
int i3 = b1 + b2; // 应该使用 int 接收
byte b3 = (byte) (b1 + b2); // 或者将结果强制转换为 byte 类型
-------------------------------
int num1 = 10;
double num2 = 20.0;
double num3 = num1 + num2; // 使用 double 接收,因为 num1 会自动提升为 double 类型

# 字符串的 “+” 操作

当 “+” 操作中出现字符串时,这个”+” 是字符串连接符,而不是算术运算。

System.out.println("itheima"+ 666); // 输出:itheima666

在”+” 操作中,如果出现了字符串,就是连接运算符,否则就是算术运算。当连续进行 “+” 操作时,从左到右逐个执行。

System.out.println(1 + 99 + "年黑马"); // 输出:199 年黑马
System.out.println(1 + 2 + "itheima" + 3 + 4); // 输出:3itheima34
// 可以使用小括号改变运算的优先级 
System.out.println(1 + 2 + "itheima" + (3 + 4)); // 输出:3itheima7

# 赋值运算符

赋值运算符的作用是将一个表达式的值赋给左边,左边必须是可修改的,不能是常量。

符号作用说明
=赋值a=10,将 10 赋值给变量 a
+=加后赋值a+=b,将 a+b 的值给 a
-=减后赋值a-=b,将 a-b 的值给 a
*=乘后赋值a*=b,将 a×b 的值给 a
/=除后赋值a/=b,将 a÷b 的商给 a
%=取余后赋值a%=b,将 a÷b 的余数给 a

注意:扩展的赋值运算符隐含了强制类型转换。

short s = 10;
s = s + 10; // 此行代码报出,因为运算中 s 提升为 int 类型,运算结果 int 赋值给 short 可能损失精度
s += 10; // 此行代码没有问题,隐含了强制类型转换,相当于 s = (short) (s + 10);

# 自增自减运算符

符号作用说明
++自增变量的值加 1
--自减变量的值减 1

注意事项:

++和-- 既可以放在变量的后边,也可以放在变量的前边。

单独使用的时候, ++和-- 无论是放在变量的前边还是后边,结果是一样的。

参与操作的时候,如果放在变量的后边,先拿变量参与操作,后拿变量做++或者--。

参与操作的时候,如果放在变量的前边,先拿变量做++或者--,后拿变量参与操作。

最常见的用法:单独使用。
int j = 10;
++j; // 单独使用
System.out.println("j:" + j); // j:11
int x = 10;
int y = x++; // 赋值运算,++ 在后边,所以是使用 x 原来的值赋值给 y,x 本身自增 1
System.out.println("x:" + x + ", y:" + y); // x:11,y:10
int m = 10;
int n = ++m; // 赋值运算,++ 在前边,所以是使用 m 自增后的值赋值给 n,m 本身自增 1
System.out.println("m:" + m + ", m:" + m); // m:11,m:11

# 关系运算符

关系运算符有 6 种关系,分别为小于、小于等于、大于、等于、大于等于、不等于。

符号说明
==a==b,判断 a 和 b 的值是否相等,成立为 true,不成立为 false
!=a!=b,判断 a 和 b 的值是否不相等,成立为 true,不成立为 false
>a>b,判断 a 是否大于 b,成立为 true,不成立为 false
>=a>=b,判断 a 是否大于等于 b,成立为 true,不成立为 false
<a<b,判断 a 是否小于 b,成立为 true,不成立为 false
<=a<=b,判断 a 是否小于等于 b,成立为 true,不成立为 false

注意事项:

关系运算符的结果都是 boolean 类型,要么是 true,要么是 false。

千万不要把 “” 误写成 “=”,""是判断是否相等的关系,"=" 是赋值。

# 逻辑运算符

逻辑运算符把各个运算的关系表达式连接起来组成一个复杂的逻辑表达式,以判断程序中的表达式是否成立,判断的结果是 true 或 false。

符号作用说明
&逻辑与a&b,a 和 b 都是 true,结果为 true,否则为 false
|逻辑或a|b,a 和 b 都是 false,结果为 false,否则为 true
^逻辑异或a^b,a 和 b 结果不同为 true,相同为 false
!逻辑非!a,结果和 a 的结果正好相反
// 定义变量
int i = 10;
int j = 20;
int k = 30;
//& “与”,并且的关系,只要表达式中有一个值为 false,结果即为 false
System.out.println((i > j) & (i > k)); //false & false, 输出 false
System.out.println((i < j) & (i > k)); //true & false, 输出 false
System.out.println((i > j) & (i < k)); //false & true, 输出 false
System.out.println((i < j) & (i < k)); //true & true, 输出 true
System.out.println("--------");
//| “或”,或者的关系,只要表达式中有一个值为 true,结果即为 true
System.out.println((i > j) | (i > k)); //false | false, 输出 false
System.out.println((i < j) | (i > k)); //true | false, 输出 true
System.out.println((i > j) | (i < k)); //false | true, 输出 true
System.out.println((i < j) | (i < k)); //true | true, 输出 true
System.out.println("--------");
//^ “异或”,相同为 false,不同为 true
System.out.println((i > j) ^ (i > k)); //false ^ false, 输出 false
System.out.println((i < j) ^ (i > k)); //true ^ false, 输出 true
System.out.println((i > j) ^ (i < k)); //false ^ true, 输出 true
System.out.println((i < j) ^ (i < k)); //true ^ true, 输出 false
System.out.println("--------");
//! “非”,取反
System.out.println((i > j)); //false
System.out.println(!(i > j)); //!false,, 输出 true

# 短路逻辑运算符

符号作用说明
&&短路与作用和 & 相同,但是有短路效果
||短路或作用和 | 相同,但是有短路效果

在逻辑与运算中,只要有一个表达式的值为 false,那么结果就可以判定为 false 了,没有必要将所有表达式的值都计算出来,短路与操作就有这样的效果,可以提高效率。同理在逻辑或运算中,一旦发现值为 true,右边的表达式将不再参与运算。

  • 逻辑与 &,无论左边真假,右边都要执行。

  • 短路与 &&,如果左边为真,右边执行;如果左边为假,右边不执行。

  • 逻辑或 |,无论左边真假,右边都要执行。

  • 短路或 ||,如果左边为假,右边执行;如果左边为真,右边不执行。

int x = 3;
int y = 4;
System.out.println((x++ > 4) & (y++ > 5)); // 两个表达都会运算
System.out.println(x); // 4
System.out.println(y); // 5
System.out.println((x++ > 4) && (y++ > 5)); // 左边已经可以确定结果为 false,右边不参与运算
System.out.println(x); // 4
System.out.println(y); // 4

# 三元运算符

三元运算符语法格式:

关系表达式 ? 表达式1 : 表达式2;

解释:问号前面的位置是判断的条件,判断结果为 boolean 型,为 true 时调用表达式 1,为 false 时调用表达式 2。其逻辑为:如果条件表达式成立或者满足则执行表达式 1,否则执行第二个。

举例:

int a = 10;
int b = 20;
int c = a > b ? a : b; // 判断 a>b 是否为真,如果为真取 a 的值,如果为假,取 b 的值

# 数据输入

我们可以通过 Scanner 类来获取用户的输入。使用步骤如下:

1、导包。Scanner 类在 java.util 包下,所以需要将该类导入。导包的语句需要定义在类的上面。

import java.util.Scanner;

2、创建 Scanner 对象。

Scanner sc = new Scanner(System.in);// 创建 Scanner 对象,sc 表示变量名,其他均不可变

3、接收数据

int i = sc.nextInt(); // 表示将键盘录入的值作为 int 数返回。

示例:

import java.util.Scanner;
public class ScannerDemo {
	public static void main(String[] args) {
		// 创建对象
		Scanner sc = new Scanner(System.in);
		// 接收数据
		int x = sc.nextInt();
		// 输出数据
		System.out.println("x:" + x);
	}
}

# 流程控制语句

# 流程控制语句分类

顺序结构

分支结构(if, switch)

循环结构(for, while, do…while)

# 顺序结构

顺序结构是程序中最简单最基本的流程控制,没有特定的语法结构,按照代码的先后顺序,依次执行,程序中大多数的代码都是这样执行的。

# 分支结构之 if 语句

# if 语句格式 1

格式:
if (关系表达式) {
    语句体;	
}

执行流程:

①首先计算关系表达式的值

②如果关系表达式的值为 true 就执行语句体

③如果关系表达式的值为 false 就不执行语句体

④继续执行后面的语句内容

public class IfDemo {
	public static void main(String[] args) {
		System.out.println("开始");	
		// 定义两个变量
		int a = 10;
		int b = 20;	
		// 需求:判断 a 和 b 的值是否相等,如果相等,就在控制台输出:a 等于 b
		if(a == b) {
			System.out.println("a等于b");
		}		
		// 需求:判断 a 和 c 的值是否相等,如果相等,就在控制台输出:a 等于 c
		int c = 10;
		if(a == c) {
			System.out.println("a等于c");
		}		
		System.out.println("结束");
	}
}

# if 语句格式 2

格式:
if (关系表达式) {
    语句体1;	
} else {
    语句体2;	
}

执行流程:

①首先计算关系表达式的值

②如果关系表达式的值为 true 就执行语句体 1

③如果关系表达式的值为 false 就执行语句体 2

④继续执行后面的语句内容

示例:

public class IfDemo02 {
	public static void main(String[] args) {
		System.out.println("开始");		
		// 定义两个变量
		int a = 10;
		int b = 20;
		b = 5;	
		// 需求:判断 a 是否大于 b,如果是,在控制台输出:a 的值大于 b,否则,在控制台输出:a 的值不大于 b
		if(a > b) {
			System.out.println("a的值大于b");
		} else {
			System.out.println("a的值不大于b");
		}		
		System.out.println("结束");
	}
}

if 语句案例:奇偶数

需求:任意给出一个整数,请用程序实现判断该整数是奇数还是偶数,并在控制台输出该整数是奇数还是偶数。

分析:

①为了体现任意给出一个整数,采用键盘录入一个数据

②判断整数是偶数还是奇数要分两种情况进行判断,使用 if..else 结构

③判断是否偶数需要使用取余运算符实现该功能 number % 2 == 0

④根据判定情况,在控制台输出对应的内容

import java.util.Scanner;
public class IfTest01 {
	public static void main(String[] args) {
		// 为了体现任意给出一个整数,采用键盘录入一个数据。(导包,创建对象,接收数据)
		Scanner sc = new Scanner(System.in);		
		System.out.println("请输入一个整数:");
		int number = sc.nextInt();	
		if(number%2 == 0) {
			System.out.println(number + "是偶数");
		} else {
			System.out.println(number + "是奇数");
		}	
	}
}

# if 语句格式 3

格式:
if (关系表达式1) {
    语句体1;	
} else if (关系表达式2) {
    语句体2;	
} else {
    语句体n+1;
}
更新于