1 Java 概述
2014 Java8
2017 Java9
Java11 LTS版
2 Java 程序设计环境
2.1 Java 术语
JDK: Java开发工具(包含JRE)
JRE: Java运行环境
Java SE (Standard Edition) 标准版本:用于桌面或者简单服务器应用的Java平台
Java EE (Enterprise Edition) 企业版本:用于复杂服务器应用的Java平台
Java ME (Micro Edition) 微型版本:用于小型设备的Java平台
NetBeans:Oracle公司的集成开发环境
2.2 命令行工具编译运行
javac 是一个 Java 编译器,将文件 Welcome.java 编译成 Welcome.class,java 程序启动 Java 虚拟机,虚拟机执行类文件中的字节码
1 | javac Welcome.java |
注意:
java Welcome
,java 区分大小写- javac 需要文件名(Welcome.java),而运行程序时,只需指定类名,不需要带扩展名
.java
或.class
常见错误及解决方法:
https://docs.oracle.com/javase/tutorial/getStarted/problems/index.html
2.3 JShell
Java 9 以上,交互式窗口
那么何时开始使用IDE工具呢?标准是:如果你还离不开这个IDE工具,那么你就不能使用这个IDE工具;只有当你十分清楚在IDE工具里单击每一个菜单,单击每一个按钮……IDE工具在底层为你做的每个细节时,才可以使用IDE工具!
3 Java 基本程序设计
3.1 简单结构
1 | public class FirstSample { |
注意:
- Java 区分大小写
- Java 类名必须以字母开头,后面跟字母和数字的组合,长度基本没有限制,但不能用 Java 保留字。采用驼峰命名法(camel case),CamelCase
- 源代码文件名必须与公共类名字相同,并用
.java
为拓展名 - main 方法必须声明为 public
3.2 注释
1 | // |
3.3 数据类型
强类型语言,8中基本类型
3.3.1 整型
类型 | 字节数 | 取值范围 |
---|---|---|
int | 4 | -2147483648~2147483647(刚超过20亿) |
short | 2 | -32 768~32 767 |
long | 8 | -9223372036854775808~9223372036854775807 |
byte | 1 | -128~127 |
- long 类型后面有一个后缀 L 或 l (40000000L)。十六进制 0x 或 0X。八进制前缀 0
- Java 7 开始加上前缀 0b 或 0B 可以写二进制数。另外还可以为数字变量加上下划线,如 1_000_000 表示 100 万
3.3.2 浮点类型
类型 | 字节数 | 有效位数 |
---|---|---|
float | 4 | 6~7位 |
double | 8 | 15位 |
float 类型后有一个后缀 F 或 f ,没有后缀的浮点数值默认为 double 类型
三个特殊的浮点数值:
正无穷大、负无穷大、NaN(不是一个数字)
Double.POSITIVE_INFINITY、Double.NEGATIVE_INFINITY、Double.NaN分别表示这三个特殊值
==注意判断时不能直接 == ,使用Double.isNaN
方法判断====浮点值不适用于无法接受舍入误差的金融计算==
如,System.out.println(2.0-1.1)
将打印出 0.8999999999999999 而不是 0.9,这是因为浮点数值采用二进制系统表示,在其中无法精确地表示分数 1/10,对于这种情况换用BigDecimal
类
3.3.3 char 类型
最好不要使用这种类型
1个java的char字符并不完全等于一个unicode的字符。char采用的UCS-2编码,是一种淘汰的UTF-16编码,编码方式最多有65536种,远远少于当今Unicode拥有11万字符的需求。java只好对后来新增的Unicode字符用2个char拼出1个Unicode字符。导致String中char的数量不等于unicode字符的数量。
3.3.4 boolean 类型
boolean 只有两个值 true 和 false
- java中 true != 1,false != 0
3.4 变量与常量
Java 10 开始,可以使用 var 关键字而无需指定类型
1 | var a = 12; |
3.4.1 常量
用 final
指示常量,表示这个常量只能被赋值一次。习惯上,常量名使用全大写。
3.4.2 枚举类型
1 | public enum Size {SMALL, MEDIUM, LARGE} |
3.5 运算符
3.6 字符串
字符串用双引号括起来
子串
1
2String greeting = "Hello";
String s = greeting.substring(0, 3);//左闭右开思想拼接
1
String message = "Hello" + "World";
连在一起,用界定符分隔,用
join
方法:1
2String all = String.join("/", "S", "M", "L", "XL");
// all is string "S/M/L/XL"Java 11 还提供了一个 repeat 方法:
1
2String repeated = "Java".repeat(3);
// "JavaJavaJava"比较字符串是否相等判断字符串相等
1
"Hello".equals(greeting);
构建字符串
1
2
3
4StringBuilder builder = new StringBuilder();//Java5+
builder.append(ch);
builder.append(str);
String myString = builder.toString();
3.7 输入与输出
3.7.1 读取输入
首先构造一个与 System.in 相关联的 Scanner 对象,然后使用 Scanner 对象的方法进行读取
Scanner 对象属于 java.util 包,==不属于 java.lang 包的,都需要 import==
1 | import java.util.*; |
Java 6 引入 Console 类读取密码:
1 | Console cons = System.console(); |
3.7.2 格式化输出
System.out.print 和 C 语言的语法差不多
格式化打印时间:
1 | System.out.printf("%tc", new Date()); |
一个参数可被多次使用,添加索引方式,索引必须以 %
开头,以 $
结束
1 | System.out.printf("%1$s %2$tB %2$tm, %2$tY", "Due date: ", new Date()); |
也可以使用 <
知识前面的参数将被再次使用
1 | System.out.printf("%s %tB %<tm, %<tY", "Due date: ", new Date()); |
3.7.3 文件输入输出
3.8 大数
BigInteger 和 BigDecimal 可以分实现任意精度的整数和浮点数的计算
valueof 方法将普通的数值转化成大数:
1 | BigInteger a = BigInteger.valueOf(100); |
不能使用算法运算符(+和*)处理大数,而需要使用 add 和 multipy 方法
4 对象与类
4.1 访问控制符
- private —— 仅对本类可见
- public —— 对外部完全可见
- protected —— 对本包和所有子类可见
- 默认,不需要修饰符 —— 对本包可见
4.2 包
用命令行编译运行带包的 java 文件层,需要在上一层且带上包名
1 | javac inheritance\ManagerTest.java |
5 继承
5.1 类,超类和子类
已存在的类被称为超类(superclass)、基类(base class)或父类(parent class);新类被称为子类(subclass)、派生类(derived class)或孩子类(child class)
1 | package com.horstmann.corejava; |
1 | public class Manager extends Employee{ |
覆盖方法
1 | public double getSalary(){ |
子类构造器
1 | public Manager(String name, double salary, int year, int month, int day){ |
5.1.1 阻止继承:final 类和方法
阻止派生 Executive 类的子类
1 | public final class Executiv extends Manager{ |
同样设置方法为 final ,子类就不可以覆盖这个方法
1 | public class Employee{ |
5.1.2 抽象类
抽象类声明抽象的方法,具体实现是在子类。抽象类方便方法调用。
1 | package abstractClasses; |
5.2 Object:所有类的超类
可以用 Object 类型变量引用任何类型的对象。具体操作时需要进行强制类型转换
1 | Object obj = new Employee("Hacker", 3500); |
只有基本类型不是对象,所有数组类型,包括基本类型的数组都拓展了 Object 类
5.3 泛型数组列表
Java 中允许在运行中确定数组的大小,更简单的方法是使用 ArrayList 类,类似于数组,但在添加或删除元素的时候,能自动调整数组容量。
尖括号中类型参数不允许是基本类型
1 | ArrayList<Employee> staff = new ArrayList<Employee>(); |
5.4 反射
https://javasec.org/javase/Reflection/Reflection.html
6 接口、lambda 表达式与内部类
6.1 接口
接口不是类,而是对希望符合这个接口的类的一组需求。
Comparable 接口代码:
1 | public interface Comparable<T>{ |
在接口中所有方法都自动是 public,不过在实现的时候,必须把方法声明为 public
1 | public class Employee implements Comparable<Employee> |
为什么不把接口设计为抽象类呢?
一个类智能继承一个类但能实现多个接口。
Java 设计者选择了不支持多重继承,因为其会让语言变得非常复杂或者降低效率。
6.2 lambda 表达式
Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
1 | package lambda; |
6.3 代理
动态代理(Dynamic Proxy)的机制:可以在运行期动态创建给定接口的新类。
https://javasec.org/javase/DynamicProxy/DynamicProxy.html