Java基础知识
Java运行原理
对于跨平台的理解:
为了让平台对编程人员透明,写出可以在不同平台运行的相同源代码,Java开发出了JVM(Java虚拟机)。
在机器和编译程序之间加入了一层抽象的虚拟的机器。这台虚拟的机器在任何平台上都提供给编译程序一个的共同的接口。
编译程序只需要面向虚拟机,生成虚拟机能够理解的代码,然后由解释器来将虚拟机代码转换为特定系统的机器码执行。在Java中,这种供虚拟机理解的代码叫节码(ByteCode)(*(class文件的内容),它不面向任何特定的处理器,只面向虚拟机。每一种平台的解释器是不同的,但是实现的虚拟机是相同的。
Java源程序经过编译器编译后变成字节码,字节码由虚拟机解释执行,虚拟机将每一条要执行的字节码送给解释器,解释器将其翻译成特定机器上的机器码,然后在特定的机器上运行。
JDK
Java开发工具包(Java Development Kit),是一套用户给 Java 编程人员的开发套件,其中包含了:
- JRE (Java Runtime Envoirment):Java 运行时环境,其中最重要的部件是 JVM;
- Java 开发工具:编译工具 javac、API 生成工具 javadoc…..存放于bin文件夹;
- 核心类库 (Java API)存放于lib文件夹。
类和对象
面向过程编程和面向对象编程
向过程编程:通过一个函数去完成一件事情,而且这件事情完成之后,不会留下 任何的遗产。或者理解为:一次性。
对象编程:在完在完成一件事情时,会将事情中的实体对象抽象出来,形成「类」 的概念,事情的完成是通过类的对象之间发生关系去实现的。
类是一群对象的特征母版,对象是类的实现。
特征(类)包含的内容有:基本属性(属性)、行为(方法)。
基础语言要素
注释
代码注释是编程中非常重要的环节,往往优秀的程序员,注释写的比代码都多。
注释是不会被程序执行的。
注释可能出现的位置:
- 类、方法、属性等上部(文档注释:通过 javadoc 命令生成 API 文档,方便使 用的人阅读)
- 方法体内负责业务逻辑处理过程中(一般性注释)
单行注释
用//开头,一般用于函数内部的注释,例如变量定义,逻辑的梳理。
// 单行注释
多行注释
用/ * 开头 */结尾,一般用于函数内部的注释。
/*
第一行注释
第二行注释
*/
文档注释
在编写类的时候,文档注释一般写在类、成员变量、类变量、方法上。
使用javadoc默认标记,丰富doc文档内容。
@author:指定Java程序作者
@version:指定当前源文件的版本
@param:指定参数
@return:指定返回值
在文档注释中可以使用html标签,但是不能用自封闭的标签。
/**
* 相关的注释内容,甚至可以使用 HTML 标签
*
*/
标识符和关键字
标识符包含了 Java 中默认的关键字以及程序员自己定义的类名、方法名、变量名 等等。
标识符的命名规范:
- 只能包含数字、字母(大小写,Unicode字符)、下划线 _、美元符 $
- 不能以数字开头
- 关键字不能用作标识符
分隔符
- 花括号 {} :定义代码块,逻辑上是一个整体,包括类的主体、方法体、静 态代码块、条件和循环语句的执行体;
- 分号 ; :语句的结束,如果出现在一行中有几条语句,那么多条之间也要用 ; 隔开;
- 方括号 [] :用于数组中;
- 圆括号 () :在方法中声明形式参数,在调用方法的时候传入实际参数,表 达式优先级定义;
- 空格:单个空格、Tab 键、Enter 键,空格的出现是不会影响程序运行的,但 是良好的缩进,可以提高程序的可读性;
- 圆点 . :用于类/对象与其成员之间的分隔,表示调用类/对象的属性或者方 法。
数据类型
在Java中,数据类型分为基本数据类型和引用数据类型(类类型)。
作为强类型语言,Java在编译时,会进行严格的语法检查,每个变量在编译时,就确定了其类型。所有变量必须显式地声明类型,而且必须声明后使用。
基本数据类型
- 数值型
- 整数型:byte(-128-127)、short(15次方)、int(31次方)、long(63次方)
- 浮点型:float(38次方)、double(308次方)
- 在实际开发中,我们一般使用 int、double
- 字符型
- char:用单引号表示,Java 中使用16位的 Unicode 字符集作为编码方式。
- 表示方式
- 直接通过单个字符表示:’a’、‘9’ 等;
- 通过转义字符表示:’\t’、’\n’、’、r’、’\’;
- 直接使用 unicode 表示:’\uxxxx’。
在 Java 中是没有表现多个字符的基本数据类型的,但是在 Java 中提供了一个 String 类,去表示字符串。
- 布尔型 boolean:表示逻辑中的真和假,值只有 true / false。
在基本数据中,是可以进行类型之间的强制转化的,但是要注意,如果从低精 度的转化为高精度时不会有问题,但是从高精度转化为低精度时,可能出现精度缺失66。
运算符
算术运算符
+ - * / % ++ --
+运算符除了进行数学运算的加法之外,还可以做字符串的拼接。
++ 自增
- -自减
赋值运算符
= += -= \= *= %=
比较运算符
用于判断两个变量或者常量的大小,返回结果为 true/false。
> < <= >= == !=
逻辑运算符
运算符两边必须是 boolean 类型的变量、常量、表达式
与 && 、或者 || 、非 !。
- 与:只要有一个假就是假
- 或者:只要有一个真就是真
三目运算符
expression ? if-true-statement : if-false-statement
实例:
int age = 16;
String ageStr = age > 18 ? "成年" : "未成年";
System.out.println(ageStr); // 未成年
结合性和优先级
应该尽量在比较复杂的表达式中使用圆括号,明确的标注计算的优先级。
流程控制
- 顺序结构
- 判断(分支选择)结构
- 循环结构
顺序结构
程序是一个自上而下运行的过程。
分支选择结构
Java 中的分支选择结构有 if 结构、switch 结构。
if 结构
具备三种类型的结构表现形式
- 形式一:
if (logic expression) {
statement;
}
int age = 20;
if (age > 18) {
String name = "Tom";
System.out.println("我叫" + name + ",已经" + age + "岁了,我成 年了!");
}
- 形式二:
if (logic expression) {
statement;
} else {
statement;
}
int age = 16;
if (age > 18) {
String name = "Tom";
System.out.println("我叫" + name + ",已经" + age + "岁了,我成 年了!");
} else {
System.out.println("我还未成年!");
}
- 形式三:
if (logic expression) {
statement;
} else if (logic expression) {
statement;
} else {
statement;
}
if (age >= 0 && age <= 10) {
System.out.println("少年");
} else if (age <= 18) {
System.out.println("青少年");
} else if (age <= 30) {
System.out.println("青年");
} else if (age <= 50) {
System.out.println("中年");
} else {
System.out.println("老年");
}
switch 结构
swtich 语句是有控制表达式和多个 case 标签块组成。在控制表达式中,只允许出 现 byte、short、int、char四种基础数据类型,在JDK1.7以后,支持 String 类型的 控制表达式。
switch (expression) {
case condition1 : {
statement;
}
case condition2 : {
statement;
}
default : {
statement;
break;
}
}
String color = "red";
switch (color) {
case "red": {
System.out.println("红色");
break;
}
case "blue": {
System.out.println("蓝色");
break;
}
case "green": {
System.out.println("绿色");
break;
}
default: {
System.out.println("没有找到");
break;
}
}
在 case 中要加入 break 关键字跳出;
在实际的开发中,我们一般使用 if - else 结构替代 switch。swtich 结构应用的 较少。
循环结构
循环语句可以在满足循环条件的情况下,反复执行某一段代码。
被重复执行的代码叫做循环体。
循环语句可能包含的部分有:
- 初始化语句(init_statement):一条或多条语句,这些语句用于完成一些初始 化的工作。
- 循环条件(test_expression):是一个 boolean 类型的表达式,这个表达式决 定是否继续执行循环体。
- 循环体(body_statement):如果条件允许,循环体会被反复执行。
- 迭代语句(iteration_statement):在一次循环体执行结束后,对循环体条件进行求值,通常用于控制循环条件中的变量,使得循环在合适的时候结束。
while结构
(init_statement);
while (test_expression) {
body_statement;
[iteration_statement];
}
int sum = 0;
int i = 1;
while (i <= 10) {
sum = sum + i;
}
System.out.println(sum); // 55
do-while 结构
(init_statement);
do {
body_statement;
[iteration_statement];
} while (test_expression)
无论如何都会执行一次循环体内容
int i = 1;
int sum = 0;
do {
sum += i++;
} while (i <= 10);
System.out.println(sum); // 11
for循环
语法:
for ([init_statement]; test_expression; [iteration_statement]) {
body_statement;
}
实例:
int sum = 0;
for (int i = 1; i <= 28; i++) {
sum = sum + i;
}
System.out.println(sum);
在实际的开发中,对于已知循环次数的遍历,一般使用 for 循环。而且 for 循环 的应用场景要比 while 循环多。
控制循环结构
break:在循环体中,使用 break 关键字跳出整个循环。
int sum = 0;
for (int i = 1; i <= 10; i++) {
sum = sum + i;
if (i == 6) {
break;
}
}
System.out.println(sum); // 21
continue:在循环体中,使用continue跳出本次循环,循环还会继续执行。
int sum = 0;
for (int i = 1; i <= 10; i++) {
if (i % 2 == 0) {
continue;
}
sum = sum + i;
}
System.out.println(sum); // 25
数组结构
数组是编程语言中最常用的一种数据类型。可以存储多个数据。
数组的要点
- 存放的数据是相同的数据类型
- 数组的长度在定义时就确定了大小,数组是不可变长度的,或者说叫定长
- 数组中可以存放任意的数据类型(包含基本数据类型、引用数据类型、数组)
- 数组本身是引用数据类型(在栈内存中会存储其在堆内存中的引用地址)
定义语法
type[] 变量名; // 强烈建议用这种命名
type 变量名[]; // 只要知道就可以
数组的初始化
在 Java 语言中,数组必须先被初始化,才能被使用。所谓的初始化,就是在内存 中为数组元素分配空间,并未每个元素赋予初始值。
- 静态初始化:显式的指定每个数组元素的值,由系统来决定数组的大小;
- 动态初始化:只需要指定数组的长度,通过程序动态的给每个元素赋值
静态初始化
语法:
type[] arrayName = {element1, element2,....}; // 比较常见
type[] arrayName = new type[]{element1, element2,...};
int[] arrs2;
arrs2 = new int[]{1, 2, 3, 4};
int[] arrs = {1, 2, 3, 4}; // 简写
动态初始化
语法:
type[] arrayName = new type[length];
数组中的索引,通过 arrayName[index] 获取指定位置的数据,index 从 0 开 始,最大值为 length-1
- 通过数组索引方式对数组元素进行赋值时,使用数组.length属性作为 for 循环 的条件。
- 在对数组元素进行操作时,一般使用 for 循环结构。
for (int i = 0; i < arrs3.length; i++) {
arrs3[i] = (i+1) * 10;
}
for (int i = 0; i < arrs3.length; i++) {
System.out.println(arrs3[i]);
}
foreach 遍历数组
for (type element : array | collections) {
element...
}
实例:
for (int a : arr3) {
System.out.println(a);
}
使用 foreach 一般情况下,值用作遍历数据,如果要对数组中元素进行修改, 还是需要使用 for 循环带索引的方式进行,因为在上述的代码中,a 只是循环 元素的一个副本。
- 理解各种数据类型在内存中的分配情况