Java方法与构造方法

方法的命名规则

  • 方法的名字的第一个单词应以小写字母作为开头,后面的单词则用大写字母开头写,不使用连接符。例如:addPerson
  • 下划线可能出现在 JUnit 测试方法名称中用以分隔名称的逻辑组件。一个典型的模式是:test<MethodUnderTest>_<state>,例如 testPop_emptyStack

方法的定义

一般情况下,定义一个方法包含以下语法:

1
2
3
4
5
6
修饰符 返回值类型 方法名(参数类型 参数名){
...
方法体
...
return 返回值;
}

方法包含一个方法头和一个方法体。下面是一个方法的所有部分:

  • **修饰符:**修饰符,这是可选的,告诉编译器如何调用该方法。定义了该方法的访问类型
  • **返回值类型 :**方法可能会返回值。returnValueType 是方法返回值的数据类型。有些方法执行所需的操作,但没有返回值。在这种情况下,returnValueType 是关键字void
  • **方法名:**是方法的实际名称。方法名和参数表共同构成方法签名
  • **参数类型:**参数像是一个占位符。当方法被调用时,传递值给参数。这个值被称为实参或变量。参数列表是指方法的参数类型、顺序和参数的个数。参数是可选的,方法可以不包含任何参数
  • **方法体:**方法体包含具体的语句,定义该方法的功能

方法的重载

上面使用的max方法仅仅适用于int型数据。但如果你想得到两个浮点类型数据的最大值呢?

解决方法是创建另一个有相同名字但参数不同的方法,如下面代码所示:

1
2
3
4
5
6
public static double max(double num1, double num2) {
if (num1 > num2)
return num1;
else
return num2;
}

如果你调用max方法时传递的是int型参数,则 int型参数的max方法就会被调用;

如果传递的是double型参数,则double类型的max方法体会被调用,这叫做方法重载;

就是说一个类的两个方法拥有相同的名字,但是有不同的参数列表。

Java编译器根据方法签名判断哪个方法应该被调用。

方法重载可以让程序更清晰易读。执行密切相关任务的方法应该使用相同的名字。

重载的方法必须拥有不同的参数列表。你不能仅仅依据修饰符或者返回类型的不同来重载方法。

变量作用域

变量的范围是程序中该变量可以被引用的部分。

方法内定义的变量被称为局部变量。

局部变量的作用范围从声明开始,直到包含它的块结束。

局部变量必须声明才可以使用。

方法的参数范围涵盖整个方法。参数实际上是一个局部变量。

for循环的初始化部分声明的变量,其作用范围在整个循环。

但循环体内声明的变量其适用范围是从它声明到循环体结束。它包含如下所示的变量声明:

你可以在一个方法里,不同的非嵌套块中多次声明一个具有相同的名称局部变量,但你不能在嵌套块内两次声明局部变量。

命令行参数的使用

有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。

命令行参数是在执行程序时候紧跟在程序名字后面的信息。

实例

下面的程序打印所有的命令行参数:

1
2
3
4
5
6
7
public class CommandLine {
public static void main(String[] args){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}

运行程序输出:

1
2
3
4
5
6
7
public class CommandLine {
public static void main(String[] args){
for(int i=0; i<args.length; i++){
System.out.println("args[" + i + "]: " + args[i]);
}
}
}

构造方法(构造器)

构造方法(Constructor)是用于创建类的对象的特殊方法。当使用 new 关键字创建对象时,构造方法会自动调用,用来初始化对象的属性。

构造方法特点

  • 方法名与类名相同:构造方法的名字必须和类名一致。
  • 没有返回类型:构造方法没有返回类型,连 void 也不能写。
  • 在创建对象时自动调用:每次使用 new 创建对象时,都会自动调用构造方法。
  • 可以重载:可以为同一个类定义多个构造方法,但这些构造方法的参数列表必须不同(即构成重载)。

不管你是否自定义构造方法,所有的类都有构造方法,因为 Java 自动提供了一个默认构造方法,默认构造方法的访问修饰符和类的访问修饰符相同(类为 public,构造函数也为 public;类改为 protected,构造函数也改为 protected)。

一旦你定义了自己的构造方法,默认构造方法就会失效。

下面是一个使用构造方法的例子:

1
2
3
4
5
6
7
8
9
// 一个简单的构造函数
class MyClass {
int x;

// 以下是构造函数
MyClass(int i ) {
x = i;
}
}

实例

1
2
3
4
5
6
7
public class ConsDemo {
public static void main(String[] args) {
MyClass t1 = new MyClass( 10 );
MyClass t2 = new MyClass( 20 );
System.out.println(t1.x + " " + t2.x);
}
}

输出

1
10 20

构造方法的类型

📌 1. 无参构造方法

无参数的构造方法,不接受任何参数,通常用于初始化默认值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person {
String name;
int age;

// 无参构造方法
public Person() {
name = "未知";
age = 18;
}

void display() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person(); // 调用无参构造
p1.display(); // 输出:姓名:未知,年龄:18
}
}

📌 2. 有参构造方法

带参数的构造方法,可以在创建对象时传递参数进行初始化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Person {
String name;
int age;

// 有参构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}

void display() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person("张三", 25); // 调用有参构造
p1.display(); // 输出:姓名:张三,年龄:25
}
}

⚠️ 注意:

  • 这里的 this.name = name; 用于区分成员变量 name 和 形参 name
  • this 代表当前对象。

📌 3. 构造方法重载

一个类可以有多个构造方法(参数列表不同),这就是构造方法的重载

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
class Person {
String name;
int age;

// 无参构造
public Person() {
this("默认姓名", 18); // 调用另一个构造方法
}

// 有参构造
public Person(String name, int age) {
this.name = name;
this.age = age;
}

void display() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person(); // 调用无参构造
p1.display(); // 输出:姓名:默认姓名,年龄:18

Person p2 = new Person("李四", 30); // 调用有参构造
p2.display(); // 输出:姓名:李四,年龄:30
}
}

💡 重点

  • this("默认姓名", 18); 代表调用另一个构造方法,避免重复代码。

📌 4. 复制构造方法

用于创建一个新对象,并复制已有对象的属性。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
class Person {
String name;
int age;

// 有参构造
public Person(String name, int age) {
this.name = name;
this.age = age;
}

// 复制构造方法
public Person(Person p) {
this.name = p.name;
this.age = p.age;
}

void display() {
System.out.println("姓名:" + name + ",年龄:" + age);
}
}

public class Main {
public static void main(String[] args) {
Person p1 = new Person("王五", 28);
Person p2 = new Person(p1); // 复制 p1
p2.display(); // 输出:姓名:王五,年龄:28
}
}

💡 重点

  • Person(Person p)复制构造方法,用于复制对象的属性。

📌 5. 私有构造方法

构造方法可以是 private,用于:

  1. 单例模式(Singleton Pattern)。
  2. 禁止外部创建对象(比如工具类)。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class Singleton {
private static Singleton instance;

// 私有构造方法
private Singleton() {}

// 获取唯一实例
public static Singleton getInstance() {
if (instance == null) {
instance = new Singleton();
}
return instance;
}

void showMessage() {
System.out.println("我是单例对象!");
}
}

public class Main {
public static void main(String[] args) {
Singleton obj1 = Singleton.getInstance();
obj1.showMessage(); // 输出:我是单例对象!
}
}

💡 重点

  • private Singleton() 使得外部不能 new Singleton();
  • 通过 getInstance() 方法获取唯一实例。

6️⃣ 构造方法 vs 普通方法

特性 构造方法 普通方法
方法名 与类名相同 任意
是否有返回值 ❌ 不能有返回值类型 ✅ 可以有返回值
调用方式 创建对象时自动调用 手动调用
作用 初始化对象 实现功能

示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Demo {
int num;

// 构造方法
public Demo() {
num = 10;
System.out.println("构造方法被调用");
}

// 普通方法
public void show() {
System.out.println("普通方法被调用");
}
}

public class Main {
public static void main(String[] args) {
Demo d = new Demo(); // 构造方法自动调用
d.show(); // 手动调用普通方法
}
}

💡 重点

  • 构造方法new自动调用,不能手动调用。
  • 普通方法 需要手动调用,如 obj.show();

构造方法中的 this 关键字

在构造方法中,this 关键字通常用于两种情况:

**1、引用当前对象的属性或方法:**当构造方法的参数名与类属性名相同时,使用 this 来区分类属性和参数。例如:

1
2
3
4
public Person(String name, int age) {
this.name = name; // this.name 表示类的属性
this.age = age;
}

**2、调用另一个构造方法:**可以使用 this() 调用当前类的其他构造方法,常用于避免重复代码,但必须放在构造方法的第一行。

1
2
3
4
5
6
7
8
public Person(String name) {
this(name, 0); // 调用另一个双参数的构造方法
}

public Person(String name, int age) {
this.name = name;
this.age = age;
}

构造方法是 Java 面向对象编程中非常重要的部分,通过使用构造方法可以有效控制对象的初始化过程,保证创建出的对象状态的完整性和一致性。

📌 7️⃣ 总结

  1. 构造方法的作用:用于初始化对象,创建对象时自动调用。

  2. 构造方法的类型:

    • ✅ 无参构造方法
    • ✅ 有参构造方法
    • ✅ 构造方法重载
    • ✅ 复制构造方法
    • ✅ 私有构造方法(用于单例模式)
  3. 构造方法 vs 普通方法:

    构造方法用于初始化,普通方法用于执行操作。

Java参数类型

在 Java 里,方法的参数可以是多种类型,下面为你详细介绍:

基本数据类型

基本数据类型是 Java 里最基础的数据类型,可直接存储数据值。Java 有 8 种基本数据类型,它们都能作为方法的参数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class PrimitiveTypeExample {
// 接收int类型参数
public static void printInt(int num) {
System.out.println("传入的整数是: " + num);
}
// 接收double类型参数
public static void printDouble(double num) {
System.out.println("传入的双精度浮点数是: " + num);
}
public static void main(String[] args) {
printInt(10);
printDouble(3.14);
}
}

引用数据类型

引用数据类型并非直接存储数据值,而是存储对象的引用(内存地址)。

  • 类类型:任何自定义类或者 Java 标准库中的类都可以作为方法参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person {
String name;
public Person(String name) {
this.name = name;
}
}
public class ClassTypeExample {
// 接收Person类对象作为参数
public static void printPerson(Person person) {
System.out.println("这个人的名字是: " + person.name);
}
public static void main(String[] args) {
Person person = new Person("张三");
printPerson(person);
}
}
  • 数组类型:数组是一种特殊的引用类型,可作为方法参数。
1
2
3
4
5
6
7
8
9
10
11
12
13
public class ArrayTypeExample {
// 接收int数组作为参数
public static void printArray(int[] arr) {
for (int num : arr) {
System.out.print(num + " ");
}
System.out.println();
}
public static void main(String[] args) {
int[] numbers = {1, 2, 3, 4, 5};
printArray(numbers);
}
}
  • 接口类型:接口也能作为方法参数,此时传入的参数必须是实现了该接口的类的对象。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
interface Shape {
double area();
}
class Circle implements Shape {
double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double area() {
return Math.PI * radius * radius;
}
}
public class InterfaceTypeExample {
// 接收Shape接口类型的参数
public static void printArea(Shape shape) {
System.out.println("该图形的面积是: " + shape.area());
}
public static void main(String[] args) {
Circle circle = new Circle(5);
printArea(circle);
}
}

可变参数

可变参数允许方法接收任意数量的同一类型参数,在方法内部可变参数会被当作数组处理。

1
2
3
4
5
6
7
8
9
10
11
12
13
public class VarargsExample {
// 可变参数方法
public static void printNumbers(int... numbers) {
for (int num : numbers) {
System.out.print(num + " ");
}
System.out.println();
}
public static void main(String[] args) {
printNumbers(1, 2, 3);
printNumbers(4, 5, 6, 7, 8);
}
}

枚举类型

枚举类型是一种特殊的类,它表示一组固定的常量。枚举类型也可以作为方法的参数。

1
2
3
4
5
6
7
8
9
10
11
12
enum Day {
MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
}
public class EnumTypeExample {
// 接收Day枚举类型的参数
public static void printDay(Day day) {
System.out.println("今天是: " + day);
}
public static void main(String[] args) {
printDay(Day.MONDAY);
}
}

综上所述,Java 方法的参数可以是基本数据类型、引用数据类型(包括类、数组、接口)、可变参数和枚举类型。