1.类的结构

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[public][abstract|final]class<class_name>[extends<class_name>][implements<interface_name>] {
// 定义成员变量
<property_type><property1>;
<property_type><property2>;
<property_type><property3>;

//如果在类中没有定义任何一个构造方法,则 Java 会自动为该类生成一个默认的构造方法。
//默认的构造方法不包含任何参数,并且方法体为空。
//如果类中显式地定义了一个或多个构造方法,则 Java 不再提供默认构造方法
<class_name>{}

// 定义方法部分
function1();
function2();
function3();

}

提示:上述语法中,中括号“[]”中的部分表示可以省略,竖线“|”表示“或关系”,例如 abstract|final,说明可以使用 abstract 或 final 关键字,但是两个关键字不能同时出现。
上述语法中各关键字的描述如下。
class_name:类的名称。
extends:表示继承其他类。
implements:表示实现某些接口。
property_type:表示成员变量的类型。
property:表示成员变量名称。
function():表示成员方法名称。

1.成员方法的结构 :

成员方法一旦被定义,便可以在程序中多次调用,提高了编程效率。声明成员方法的语法格式如下:

1
2
3
[public|private|protected][static]<void|return_type><method_name>([paramList]) {
// 方法体
}

上述代码中一个方法包含 4 部分:方法的返回值、方法名称、方法的参数和方法体。其中 retum_type 是方法返回值的数据类型,数据类型可以是原始的数据类型,即常用的 8 种数据类型,也可以是一个引用数据类型,如一个类、接口和数组等。
paramList 表示参数列表,这些变量都要有自己的数据类型,可以是原始数据类型,也可以是复杂数据类型,一个方法主要依靠参数来传递消息。

2.构造方法的结构:

Java 构造方法有以下特点:
-方法名必须与类名相同
-可以有 0 个、1 个或多个参数
-没有任何返回值,包括 void
-默认返回类型就是对象类型本身
-只能与 new 运算符结合使用
注意:构造方法不能被 static、final、synchronized、abstract 和 native修饰。构造方法用于初始化一个新对象,所以用 static 修饰没有意义。构造方法不能被子类继承,所以用 final 和 abstract 修饰没有意义。多个线程不会同时创建内存地址相同的同一个对象,所以用 synchronized 修饰没有必要

3.成员变量和局部变量

局部变量和成员变量的名字相同,则成员变量被隐藏,得使用关键字this使用成员变量

1.成员变量

Java 的成员变量有两种,分别是全局变量(实例变量)和静态变量(类变量)。

名称 修饰 访问 生命周期 作用域
全局变量(实例变量) 无 static 修饰 对象名.变量名 只要对象被当作引用,实例变量就将存在 在类内有效
静态变量(类变量) 用 static 修饰 类名.变量名或对象名.变量名 其生命周期取决于类的生命周期。类被垃圾回收机制彻底回收时才会被销毁 该局部变量所在的块作用域中位置之后

特性:

  • 成员变量创建时有默认值,默认值根据类型而定
  • 对成员变量的操作只能放在方法中,方法外不可以对成员变量操作
2.局部变量

局部变量是指在方法或者方法代码块中定义的变量,其作用域是其所在的代码块。可分为以下三种:

  • 方法参数变量(形参):在整个方法内有效。
  • 方法局部变量(方法内定义): 从定义这个变量开始到方法结束这一段时间内有效。
  • 代码块局部变量(代码块内定义):从定义这个变量开始到代码块结束这一段时间内有效。

特性:

  • 局部变量的作用域和生存期只在方法内有效,且与其声明的位置有关
  • 局部变量无初始值,在使用前必须被初始化值。

2.对象的创建 使用和销毁

1.对象的创建

1. 使用 new 关键字创建对象

这是常用的创建对象的方法,语法格式如下:

1
类名 对象名 = new 类名();
2. 调用 java.lang.Class 或者 java.lang.reflect.Constuctor 类的 newlnstance() 实例方法
1
2
java.lang.Class Class 类对象名称 = java.lang.Class.forName(要实例化的类全称);
类名 对象名 = (类名)Class类对象名称.newInstance();

调用 java.lang.Class 类中的 forName() 方法时,需要将要实例化的类的全称(比如 com.mxl.package.Student)作为参数传递过去,然后再调用 java.lang.Class 类对象的 newInstance() 方法创建对象。

3. 调用对象的 clone() 方法

该方法不常用,使用该方法创建对象时,要实例化的类必须继承 java.lang.Cloneable 接口。 调用对象的 clone() 方法创建对象的语法格式如下:

1
类名对象名 = (类名)已创建好的类对象名.clone();
4. 调用 java.io.ObjectlnputStream 对象的 readObject() 方法

2.对象的使用

每个对象都有自己的属性和行为,这些属性和行为在类中体现为成员变量和成员方法,其中成员变量对应对象的属性,成员方法对应对象的行为。

在 Java 中,要引用对象的属性和行为,需要使用点(.)操作符来访问。语法格式如下:

1
2
对象名.属性(成员变量)    // 访问对象的属性
对象名.成员方法名() // 访问对象的方法

3.对象的销毁

对象使用完之后需要对其进行清除。对象的清除是指释放对象占用的内存。在创建对象时,用户必须使用 new 操作符为对象分配内存。不过,在清除对象时,由系统自动进行内存回收,不需要用户额外处理。
Java 语言的内存自动回收称为垃圾回(GarbageCollection)机制,简称 GC。垃圾回收机制是指 JVM 用于释放那些不再使用的对象所占用的内存。一个对象被当作垃圾回收的情况主要如下两种。

1
2
3
4
1)对象的引用超过其作用范围。
{
Object o = new Object(); // 对象o的作用范围,超过这个范围对象将被视为垃圾
}
1
2
3
4
5
2)对象被赋值为 null
{
Object o = new Object();
o = null; // 对象被赋值为null将被视为垃圾
}

在 Java 的 Object 类中还提供了一个 protected 类型的 finalize() 方法,因此任何 Java 类都可以覆盖这个方法,在这个方法中进行释放对象所占有的相关资源的操作。
在 Java 虚拟机的堆区,每个对象都可能处于以下三种状态之一。
1)可触及状态:当一个对象被创建后,只要程序中还有引用变量引用它,那么它就始终处于可触及状态。
2)可复活状态:当程序不再有任何引用变量引用该对象时,该对象就进入可复活状态。在这个状态下,垃圾回收器会准备释放它所占用的内存,在释放之前,会调用它及其他处于可复活状态的对象的 finalize() 方法,这些 finalize() 方法有可能使该对象重新转到可触及状态。
3)不可触及状态:当 Java 虚拟机执行完所有可复活对象的 finalize() 方法后,如果这些方法都没有使该对象转到可触及状态,垃圾回收器才会真正回收它占用的内存。
注意:调用 System.gc() 或者 Runtime.gc() 方法也不能保证回收操作一定执行,它只是提高了 Java 垃圾回收器尽快回收垃圾的可能性。

4.匿名对象

匿名对象就是没有明确的给出名字的对象,是对象的一种简写形式。一般匿名对象只使用一次,而且匿名对象只在堆内存中开辟空间,而不存在栈内存的引用。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Person {
public String name; // 姓名
public int age; // 年龄
// 定义构造方法,为属性初始化
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 获取信息的方法
public void tell() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
public static void main(String[] args) {
new Person("张三", 30).tell(); // 匿名对象
}
}

3.方法重载(有相同的名字,不同的参数,便产生了重载)

方法重载分为两种重载:

  • 构造方法重载
  • 方法重载

重载条件:

  • ⽅法名称必须相同。
  • 参数列表必须不同(个数不同、或类型不同、参数类型排列顺序不同等)。
  • ⽅法的返回类型可以相同也可以不相同。
  • 仅仅返回类型不同不⾜以成为⽅法的重载。
  • 重载是发⽣在编译时的,因为编译器可以根据参数的类型来选择使⽤哪个⽅法。

4.可变参数

当几个方法名称相同,功能相同,参数个数不同时,可以使用可变参数优化
声明可变参数的语法格式如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
methodName({paramList},paramType…paramName)

其中,methodName 表示方法名称;paramList 表示方法的固定参数列表;paramType 表示可变参数的类型;… 是声明可变参数的标识;paramName 表示可变参数名称。
public class StudentTestMethod {
// 定义输出考试学生的人数及姓名的方法
public void print(String...names) {
int count = names.length; // 获取总个数
System.out.println("本次参加考试的有"+count+"人,名单如下:");
for(int i = 0;i < names.length;i++) {
System.out.println(names[i]);
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
StudentTestMethod student = new StudentTestMethod();
student.print("张强","李成","王勇"); // 传入3个值
student.print("马丽","陈玲");
}
}
  • 在定义了可变参数后,我们可以像操作数组一样操作该参数,即对数组的操作也可以对可变参数操作(可变参数的本质是数组)
  • 如果该方法除了可变参数还有其它的参数,可变参数必须放到最后;
  • 调用使用了可变参数的方法时,参数可以是0个或任意个,参数之间靠逗号隔开
  • 可变参数可以传入一个数组;
  • 拥有可变参数的方法可以被重载,在被调用时,如果能匹配到参数定长的方法则优先调用参数定长的方法。
  • 一个参数列表只能有一个可变参数

5.包管理

Java 中使用 package 语句定义包,package 语句应该放在源文件的第一行,在每个源文件中只能有一个包定义语句,并且 package 语句适用于所有类型(类、接口、枚举和注释)的文件。定义包语法格式如下:

1
package 包名;

包导入:
使用 import 导入单个类的语法格式如下:

1
2
import 包名+类名;
import 包名*;//导入包内所有的类

注意:使用星号(*)可能会增加编译时间,特别是引入多个大包时,所以明确的导入你想要用到的类是一个好方法,需要注意的是使用星号对运行时间和类的大小没有影响
当两个包内有重名类时,只能导入其中一个,另一个引用时得写入完整包名,否则会发生冲突、

包的 3 个作用:

  • 区分相同名称的类。
  • 能够较好地管理大量的类。
  • 控制访问范围。