1. 概述
1.1 java整体内容概述
1.2 JDK、JRE、JVM的关系
1.3 注释:Comment
- 分类:
- 单行注释:
// - 多行注释:
/* */ - 文档注释:
/** */
- 单行注释:
- 注意: 多行注释不可以嵌套使用
2. 基本语法
2.1 关键字与标识符
2.1.1 关键字的使用
-
定义:被Java语言赋予了特殊含义,用做专门用途的字符串(单词)
-
特点:关键字中所有字母都为小写
-
具体哪些关键字:
2.1.2 标识符的使用
-
定义:凡是自己可以起名字的地方都叫标识符。
-
涉及到的结构:包名、类名、接口名、变量名、方法名、常量名
-
规则:(必须要遵守。否则,编译不通过)
-
规范:(不影响编译,但是要求遵守)
2.1.3 变量的使用
-
按数据类型分:
-
按声明的位置分类
-
详细说明:
- 整型:
byte(1字节=8bit) /short(2字节) /int(4字节) /long(8字节) ① byte范围:-128 ~ 127 ② 声明long型变量,必须以"l"或"L"结尾 ③ 通常,定义整型变量时,使用int型。 ④整型的常量,默认类型是:int型 - 浮点型:
float(4字节) /double(8字节) ① 浮点型,表示带小数点的数值 ② float表示数值的范围比long还大 ③ 定义float类型变量时,变量要以"f"或"F"结尾 ④ 通常,定义浮点型变量时,使用double型。 ⑤ 浮点型的常量,默认类型为:double - 字符型:
char(1字符=2字节) ① 定义char型变量,通常使用一对'',内部只能写一个字符 ② 表示方式:1.声明一个字符 2.转义字符 3.直接使用 Unicode 值来表示字符型常量 - 布尔型:
boolean① 只能取两个值之一:true 、 false ② 常常在条件判断、循环结构中使用
- 整型:
-
定义变量的格式:
数据类型 变量名 = 变量值; or 数据类型 变量名; 变量名 = 变量值;
-
变量使用的注意点:
-
① 变量必须先声明,后使用
-
② 变量都定义在其作用域内。在作用域内,它是有效的。换句话说,出了作用域,就失效了
-
③ 同一个作用域内,不可以声明两个同名的变量
3. 数组
3.1 数组的基本知识
-
数组的理解:数组(Array),是多个相同类型数据一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。
-
数组的特点:
-
数组是有序排列的;
-
数组属于引用数据类型的变量。数组的元素,既可以是基本数据类型,也可以是引用数据类型;
-
创建数组对象会在内存中开辟一整块连续的空间;
-
数组的长度一旦确定,就不能修改。
-
-
数组的分类:
- ① 按维数:一维数组、二维数组、。。。;
- ② 按数组元素的类型:基本数据类型元素的数组、引用数据类型元素的数组。
3.2 一维数组
3.2.1 一维数组的声明与初始化
//声明
int[] ids;
//1.1 静态初始化:数组的初始化和数组元素的赋值操作同时进行
ids = new int[]{1001,1002,1003,1004};
//1.2动态初始化:数组的初始化和数组元素的赋值操作分开进行
String[] names = new String[5];
//类型推断
int[] arr4 = {1,2,3,4,5};
3.2.2 一维数组元素的引用
- 通过角标调用
//数组的角标(或索引从0开始的,到数组的长度-1结束。
String[] names = new String[5];
names[0] = "王铭";
names[1] = "王赫";
names[2] = "张学良";
String wm = names[0];
3.2.3 一维数组的遍历
String[] names = new String[5];
//1.第一种
for(int i = 0;i < names.length;i++){
System.out.println(names[i]);
}
//2.第二种
for(String name : names){
System.out.println(names[i]);
}
3.2.4 一维数组元素的默认初始化值
//数组元素是整型:0
//数组元素是浮点型:0.0
//数组元素是char型:0或'\u0000',而非'0'
//数组元素是boolean型:false
//数组元素是引用数据类型:null
3.3 二维数组
3.3.1 怎么理解二维数组?
数组属于引用数据类型,数组的元素也可以是引用数据类型,一个一维数组的元素如果还是一个一维数组类型的,则将此数组称为二维数组。
3.3.2 二维数组的声明与初始化
//正确的方式:
int[] arr = new int[]{1,2,3};//一维数组
//静态初始化
int[][] arr1 = new int[][]{{1,2,3},{4,5},{6,7,8}};
//动态初始化1
String[][] arr2 = new String[3][2];
//动态初始化2
String[][] arr3 = new String[3][];
//也是正确的写法:
int[] arr4[] = new int[][]{{1,2,3},{4,5,9,10},{6,7,8}};
int[] arr5[] = {{1,2,3},{4,5},{6,7,8}};//类型推断
//错误的方式:
// String[][] arr4 = new String[][4];
// String[4][3] arr5 = new String[][];
// int[][] arr6 = new int[4][3]{{1,2,3},{4,5},{6,7,8}};
//[][]里面有值,后面的{}里面就不要赋值了;后面的{}里面有值,[][]里面就不要写了。
4.类与对象
- 面向对象的三条主线:
- Java类及类的成员:属性、方法、构造器;代码块、内部类;
- 面向对象的三大特征:封装性、继承性、多态性、(抽象性);
- 其它关键字:this、super、static、final、abstract、interface、package、import等。
4.1 类的成员
4.1.1 属性、方法、构造器
//这是一个类
public class Employee {
//属性,共有六个私有属性。
//public修饰符:可以在本类中,也可以在其他类中通过对象访问。
//为了封装性,属性通常都是private的
public String name;
//private是修饰符,表示只有在该类中才可以访问。
private String idCard;
private Integer age;
private Double height;
private Double weight;
private String address;
//构造器:修饰符+类名。
/*
1.如果没显式的定义类的构造器的话,则系统默认提供一个空参的构造器
2.定义构造器的格式:权限修饰符 类名(形参列表){}
3.一个类中定义的多个构造器,彼此构成重载
4.一旦我们显式的定义了类的构造器之后,系统就不再提供默认的空参构造器
5.一个类中,至少会有一个构造器。
*/
//无参构造器
//idea中可通过Shift+Alt+s快捷键选generate生成构造器
public Employee() {
}
//构造器重载
//通过构造器初始化
public Employee(String name, String idCard, Integer age, Double height, Double weight, String address) {
this.name = name;
this.idCard = idCard;
this.age = age;
this.height = height;
this.weight = weight;
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getHeight() {
return height;
}
public void setHeight(Double height) {
this.height = height;
}
public Double getWeight() {
return weight;
}
public void setWeight(Double weight) {
this.weight = weight;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + '\'' +
", idCard='" + idCard + '\'' +
", age=" + age +
", height=" + height +
", weight=" + weight +
", address='" + address + '\'' +
'}';
}
}
public class Test {
public static void main(String[] args) {
//通过无参构造器生成对象
Employee employee = new Employee();
//通过构造器初始化
Employee employee1 = new Employee("张三","123",18,172.5,105d,"江苏省南京市");
//public的属性可以被访问。
String name = employee.name;
}
}
4.1.2 可变个数形参的方法
- 形参与实参的区别
- 形参:方法定义时,声明的小括号内的参数
- 实参:方法调用时,实际传递给形参的数据
具体使用:
- 1 可变个数形参的格式:
数据类型 ... 变量名 - 2 当调用可变个数形参的方法时,传入的参数个数可以是:0个,1个,2个,。。。
- 3 可变个数形参的方法与本类中方法名相同,形参不同的方法之间构成重载
- 4 可变个数形参的方法与本类中方法名相同,形参类型也相同的数组之间不构成重载。换句话说,二者不能共存。
- 5 可变个数形参在方法的形参中,必须声明在末尾
- 6 可变个数形参在方法的形参中,最多只能声明一个可变形参。
public void show(String s){
System.out.println("show(String)");
}
//show(数据类型 ... 变量名)
public void show(String ... strs){
System.out.println("show(String ... strs)");
for(int i = 0;i < strs.length;i++){
System.out.println(strs[i]);
}
}
4.2 三大特征
4.2.1 封装性
-
为什么要引入封装性?
我们程序设计追求“高内聚,低耦合”。
- 高内聚 :类的内部数据操作细节自己完成,不允许外部干涉;
- 低耦合 :仅对外暴露少量的方法用于使用。
-
封装性思想具体的代码体现:
- 将类的属性xxx私化(private),同时**,提供公共的(public)方法来获取**(getXxx)和设置(setXxx)此属性的值;
- 不对外暴露私有的方法;
- 单例模式(将构造器私有化);
- 如果不希望类在包外被调用,可以将类设置为缺省的。
-
四种权限修饰符
修饰符 类内部 同一个包 不同包的子类 同一个工程 public √ √ √ √ protected √ √ √ 确省(默认) √ √ private √
4.2.2 继承性
-
为什么要有类的继承性?(继承性的好处)
- ① 减少了代码的冗余,提高了代码的复用性
- ② 便于功能的扩展
- ③ 为之后多态性的使用,提供了前提
-
Java中继承性的说明
- 一个类可以被多个子类继承。
- Java中类的单继承性:一个类只能有一个父类
- 子父类是相对的概念。
- 子类直接继承的父类,称为:直接父类。间接继承的父类称为:间接父类
- 子类继承父类以后,就获取了直接父类以及所有间接父类中声明的属性和方法
-
java.lang.Object类的理解- 如果我们没显式的声明一个类的父类的话,则此类继承于java.lang.Object类;
- 所的java类(除java.lang.Object类之外都直接或间接的继承于java.lang.Object类;
- 意味着,所的java类具有java.lang.Object类声明的功能。
-
重新与重载的区别
- 什么是方法的重写(
override或overwrite)?- 重写:子类继承父类以后,可以对父类中同名同参数的方法,进行覆盖操作;
- 重载:同一个类中的同一个方法的不同实现。
- 应用: 重写以后,当创建子类对象以后,通过子类对象调用子父类中的同名同参数的方法时,实际执行的是子类重写父类的方法。
- 什么是方法的重写(
4.2.3 多态性
- 多态:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
- 多态的使用:有了对象的多态性以后,在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
- 使用前提:① 类的继承关系 ② 方法的重写。
- 总结:编译,看左边;运行,看右边。
4.3 关键字
4.3.1 this
-
this可以调用属性、方法;可以理解为:当前对象 或 当前正在创建的对象
-
在类中调用属性、方法
-
在类的方法中,我们可以使用"
this.属性"或"this.方法的方式,调用当前对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果方法的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。 -
在类的构造器中,我们可以使用"
this.属性"或"this.方法”的方式,调用当前正在创建的对象属性或方法。但是,通常情况下,我们都择省略"this."。特殊情况下,如果构造器的形参和类的属性同名时,我们必须显式的使用"this.变量"的方式,表明此变量是属性,而非形参。
-
-
this调用构造器:
- ① 我们在类的构造器中,可以显式的使用"this(形参列表)"方式,调用本类中指定的其他构造器
- ② 构造器中不能通过"this(形参列表)"方式调用自己
- ③ 如果一个类中有n个构造器,则最多有 n - 1构造器中使用了"this(形参列表)"
- ④ 规定:"
this(形参列表)"必须声明在当前构造器的首行 - ⑤ 构造器内部,最多只能声明一个"this(形参列表)",用来调用其他的构造器
4.3.2 super
-
super 可以调用属性、方法、构造器;可以理解为:父类的
-
super调用属性、方法:
- 我们可以在子类的方法或构造器中。通过使用"
super.属性"或"super.方法"的方式,显式的调用父类中声明的属性或方法。但是,通常情况下,我们习惯省略"super." - 特殊情况:当子类和父类中定义了同名的属性时,我们要想在子类中调用父类中声明的属性,则必须显式的使用"super.属性"的方式,表明调用的是父类中声明的属性。
- 特殊情况:当子类重写了父类中的方法以后,我们想在子类的方法中调用父类中被重写的方法时,则必须显式的使用"super.方法"的方式,表明调用的是父类中被重写的方法。
- 我们可以在子类的方法或构造器中。通过使用"
-
super调用构造器:
- 我们可以在子类的构造器中显式的使用"
super(形参列表)"的方式,调用父类中声明的指定的构造器 - "
super(形参列表)"的使用必须声明在子类构造器的首行! - 我们在类的构造器中,针对于"this(形参列表)"或"super(形参列表)"只能二一,不能同时出现
- 在构造器的首行,没显式的声明"this(形参列表)"或"super(形参列表)",则默认调用的是父类中空参的构造器:super()
- 在类的多个构造器中,至少一个类的构造器中使用了"super(形参列表)",调用父类中的构造器
- 我们可以在子类的构造器中显式的使用"
4.3.3 static
-
静态的,主要用来修饰类的内部结构;属性、方法、代码块、内部类。
-
static 修饰属性:
-
属性的区别:是否使用static修饰,又分为:静态属性 vs 非静态属性(实例变量)
-
静态属性:创建了类的多个对象,多个对象共享同一个静态变量。当通过某一个对象修改静态变量时,会导致其他对象调用此静态变量时,是修改过了的。
-
动态属性:创建了类的多个对象,每个对象都独立的拥一套类中的非静态属性。当修改其中一个对象中的非静态属性时,不会导致其他对象中同样的属性值的修改。
- 注意点:
- 静态变量随着类的加载而加载。可以通过"
类.静态变量"的方式进行调用 - 静态变量的加载要早于对象的创建。
- 由于类只会加载一次,则静态变量在内存中也只会存在一份:存在方法区的静态域中。
- 静态变量随着类的加载而加载。可以通过"
-
-
static修饰方法:
- 随着类的加载而加载,可以通过"
类.静态方法"的方式进行调用 - 静态方法中,只能调用静态的方法或属性
- 非静态方法中,既可以调用非静态的方法或属性,也可以调用静态的方法或属性
- 在静态的方法内,不能使用
this关键字、super关键字
- 随着类的加载而加载,可以通过"
4.3.4 final
- 最终的,可以用来修饰:类、方法、变量。
- final 用来修饰一个类:此类不能被其他类所继承,比如:String类、System类、StringBuffer类;
- final 用来修饰方法:表明此方法不可以被重写,比如:Object类中getClass();
- final 用来修饰变量:此时的"变量"就称为是一个常量
-
final修饰属性:可以考虑赋值的位置:**显式初始化、代码块中初始化、构造器中初始化;** -
final修饰局部变量:尤其是使用final修饰形参时,表明此形参是一个常量。当调用此方法时,给常量形参赋一个实参。一旦赋值以后,就只能在方法体内使用此形参,但不能进行重新赋值。 -
`static final` 用来修饰属性:全局常量
-
4.3.5 abstract
-
抽象的,可以用来修饰:类、方法。
-
abstract修饰类:抽象类
-
此类不能实例化(new 对象);
-
**抽象类中一定有构造器**,便于子类实例化时调用; -
开发中,都会提供抽象类的子类,让子类对象实例化,完成相关的操作;
-
-
abstract修饰方法:抽象方法
-
抽象方法**只有方法的声明,没方法体**; -
包含**抽象方法的类,一定是一个抽象类**。反之,抽象类中可以没有抽象方法的; -
若子类**重写了父类中的所有抽象方法**后,此**子类方可实例化**; -
若子类没重写父类中的所有抽象方法,则此子类也是一个抽象类,需要使用abstract修饰
-
4.3.6 interface
-
接口使用
interface来定义; -
Java中,接口和类是并列的两个结构;
-
如何定义接口:
-
定义接口中的成员:JDK8以后:除了定义全局常量和抽象方法之外,还可以定义静态方法、默认方法;
全局常量:
public static final的.但是书写时,可以省略不写抽象方法:
public abstract的 -
接口中不能定义构造器的!意味着接口不可以实例化;
-
接口通过让类去实现(
implements)的方式来使用.- 如果实现类覆盖了接口中的所抽象方法,则此实现类就可以实例化
- 如果实现类没覆盖接口中所的抽象方法,则此实现类仍为一个抽象类
-
Java类可以实现多个接口 --->弥补了Java单继承性的局限性
- 格式:
class AA extends BB implements CC,DD,EE
- 格式:
-
接口与接口之间可以继承,而且可以多继承;
-
-
接口的具体使用,体现多态性
4.4包装类的使用
-
为什么引入包装类?为了使基本数据类型的变量具有类的特征,所以引入包装类。
-
基本数据类型与对应的包装类:包装类首字母大写
基本数据类型 包装类 byte Byte short Short int Integer long Long float Float double Double boolean Boolean char Char -
基本数据类型、包装类、String之间的相互转化