【Java】对象与类
【Java】对象与类
文章目录
- 【Java】对象与类
- 1、学习背景
- 2、定义&使用
- 2.1 创建类
- 2.2 创建对象
- 3、static关键字
- 3.1 修饰变量
- 3.2 修饰方法
- 3.3 修饰代码块
- 3.4 修饰内部类
- 4、this关键字
- 5、封装特性
- 5.1 访问修饰符
- 5.2 包的概念
- 6、构造方法
- 7、代码块
- 7.1 普通代码块
- 7.2 成员代码块
- 7.3 静态代码块
- 7.4 同步代码块
1、学习背景
在学习C++后继续学习Java,Java给我的第一感觉和C++很像,它们都是面对对象编程(OOP)语言,在很多知识上都有相似之处,这也给学习带来了方便
就从类与对象入手,先分析Java与C++在这上边的区别
-
语法差异:
- 类定义: 在C++中,类的定义可以分为头文件(.h)和实现文件(.cpp)。在Java中,一个类通常定义在一个独立的源文件中。
- 构造函数: 在C++中,构造函数和析构函数的命名与类名相同,没有返回类型。在Java中,构造函数的命名与类名相同,但没有析构函数的概念。
- 继承: 在C++中,使用
public、protected和private关键字来控制继承中的成员访问权限。在Java中,使用public、protected、private和默认(包内可见)四种访问修饰符。
-
内存管理:
- 内存分配: C++中使用
new和delete来手动管理对象的内存分配和释放。Java中的对象内存管理由垃圾回收器自动处理。 - 析构函数和垃圾回收: C++的析构函数用于对象被销毁时执行清理操作。Java中没有析构函数,垃圾回收器负责释放不再使用的对象。
- 内存分配: C++中使用
-
引用类型:
- 在C++中,可以使用引用类型来创建别名,但在Java中,没有直接的引用类型,只有对象引用。
-
继承与多态:
- C++中支持多重继承,一个类可以从多个父类派生。Java中只支持单一继承,但可以通过接口实现类似多重继承的效果。
- C++中使用虚函数和关键字
virtual来实现运行时多态性。Java中所有非静态方法默认都是虚方法,可以被子类重写。
-
访问控制:
- C++中通过
public、protected和private来控制类成员的访问权限。Java也使用类似的修饰符,包括public、protected、private和默认(包内可见)。
- C++中通过
尽管存在一些差异,但类与对象的概念在C++和Java中基本上是类似的。这两种语言都支持封装、继承、多态等面向对象的基本概念,但具体实现和一些细节方面会有一些差异。
2、定义&使用
2.1 创建类
在Java中,创建一个类需要使用特定的语法结构。下面是创建类的基本语法:
// 类的定义
public class ClassName {// 成员变量(属性)dataType variableName1;dataType variableName2;// ...// 构造方法public ClassName() {// 构造方法的代码}// 成员方法(函数)returnType methodName1(parameterType parameterName1, parameterType parameterName2, ...) {// 方法的代码}returnType methodName2(parameterType parameterName1, parameterType parameterName2, ...) {// 方法的代码}// ...
}
在上面的代码中,需要做以下几件事情:
-
类名(ClassName): 用于标识类的名称,通常采用驼峰命名法(首字母小写)。
-
成员变量(属性): 在类中定义成员变量,用于存储对象的数据。需要指定数据类型和变量名。
-
构造方法: 构造方法用于创建对象时初始化成员变量,没有返回类型,并且与类名相同。可以有多个构造方法,以支持不同的初始化方式。
-
成员方法(函数): 在类中定义成员方法,用于执行各种操作。需要指定返回类型、方法名、参数列表和方法体。
请注意以下几点:
- 成员变量和方法可以有不同的访问修饰符,如
public、private、protected或默认(包内可见)。 - 构造方法在创建对象时被调用,用于初始化对象的属性。
- 成员方法可以执行各种操作,使用返回类型指定方法的返回值类型。
以下是一个简单的例子:
public class Person {// 成员变量private String name;private int age;// 构造方法public Person(String n, int a) {name = n;age = a;}// 成员方法public void introduce() {System.out.println("My name is " + name + " and I am " + age + " years old.");}// 主方法(用于测试)public static void main(String[] args) {Person person1 = new Person("Alice", 25);person1.introduce();Person person2 = new Person("Bob", 30);person2.introduce();}
}
在这个例子中,Person 类有两个成员变量 name 和 age,一个构造方法用于初始化这些变量,以及一个 introduce 方法用于介绍人物信息。在 main 方法中,我们创建了两个 Person 对象并调用了他们的 introduce 方法。

2.2 创建对象
创建了一个类并定义了其属性和方法后,可以使用 new 关键字来实例化(创建)该类的对象。
在上面的例子中,我们已经创建了 Person 类,现在让我们继续使用该类来创建对象并调用方法。
public class Person
{// ...(之前的类定义)// 主方法(用于测试)public static void main(String[] args){Person person1 = new Person("alice",25);Person person2 = new Person("dick",13);person1.introduce();person2.introduce();}
}
在上面的代码中,我们在 main 方法中创建了两个 Person 对象 person1 和 person2。然后,我们分别调用了这两个对象的 introduce 方法,以显示它们的信息。

这就是在Java中创建对象的基本过程。通过实例化类,可以创建具有类定义属性和方法的实际对象,并通过调用对象的方法来执行特定的操作。在实际开发中,类和对象的概念是面向对象编程中非常重要的基础。
与C++不同点出现了,Java多数情况下将main方法放在类中
main方法在Java中的特殊作用是作为程序的入口点。当运行一个Java程序时,JVM会从main方法开始执行。这种设计方式使得执行流程具有明确的起点,确保了程序的可预测性和可控性。将
main方法放在类内部有几个重要的原因:
统一入口: 将
main方法置于类内部使得每个Java类都可以作为一个独立的程序执行。这样,你可以在一个项目中创建多个独立的Java程序,每个程序都有自己的入口点。访问权限: Java中的访问修饰符(如
public、private等)也适用于方法。将main方法放在类内部意味着你可以根据需要选择设置其访问权限,以便控制它是否可以被其他类访问。类的上下文:
main方法可以直接访问类中定义的成员变量和方法。这对于在程序启动时进行一些初始化操作或测试非常有用。简化执行: Java应用程序的执行流程始终从
main方法开始,这种统一入口的设计使得程序的执行过程变得清晰可见,易于理解和调试。基于以上原因,Java程序的
main方法通常被放置在类的内部作为程序的入口。当在命令行或集成开发环境(IDE)中运行Java程序时,JVM会查找并执行具有正确签名(public static void main(String[] args))的main方法。
3、static关键字
3.1 修饰变量
在Java中,使用 static 关键字来修饰变量会使这个变量成为一个静态变量(也叫类变量)。静态变量属于类而不是对象,它在类加载时被初始化,并且在整个类的生命周期内都只有一份副本,被所有实例共享。以下是关于使用 static 修饰变量的一些重要点:
-
静态变量声明: 静态变量通常在类的顶层声明,即在类的成员变量部分,但在方法和构造方法之外。它们必须使用
static关键字修饰。 -
初始化: 静态变量在类加载时会被初始化,只会执行一次。你可以在声明时直接赋值,也可以在静态代码块中进行初始化。
-
共享性: 所有类的实例共享同一个静态变量,它不属于特定的实例,而是属于整个类。
-
通过类名访问: 静态变量可以使用类名直接访问,不需要创建对象。例如,
ClassName.staticVariable。 -
在静态方法中使用: 静态变量可以在静态方法中直接使用,因为静态方法属于类而不是对象。
-
线程共享: 由于静态变量属于类,多个线程共享同一个静态变量。需要注意线程安全问题。
下面是一个使用静态变量的例子:
public class Example {// 静态变量static int count = 0;// 构造方法public Example() {count++;}// 静态方法使用静态变量public static void printCount() {System.out.println("Count: " + count);}public static void main(String[] args) {Example obj1 = new Example();Example obj2 = new Example();Example.printCount(); // 输出:Count: 2}
}
在这个例子中,count 是一个静态变量,用于计算 Example 类的实例数量。通过每次创建对象时递增 count,最终可以得到对象的总数。静态方法 printCount 可以直接访问静态变量 count,因为它们都属于类本身。
3.2 修饰方法
方法与函数
方法(Method)和函数(Function)在编程中基本上是相同的概念,尤其在讨论通用性时。它们都表示一段可重复使用的代码块,用于执行特定的操作或完成特定的任务。然而,它们的使用和命名可能因编程语言而异。
在面向对象编程(OOP)中,尤其是在Java等一些编程语言中,我们更常用术语“方法”来表示属于类或对象的行为。方法是对象的行为,它们通常用于在对象上执行操作、访问数据或执行一些功能。
在一些非面向对象的编程语言(如C语言),我们更常用术语“函数”来表示可重用的代码块,它们可以独立于对象存在。这些函数可以接受参数,执行一些操作,并返回一个值。在这种情况下,函数不一定与对象相关联,它们可以是独立的代码模块。
虽然在一些语言中术语可能会有所不同,但在大多数情况下,方法和函数都指代相似的概念:可重用的代码块,用于执行特定的操作或完成任务。无论使用哪个术语,它们都是编程中非常重要的概念,用于模块化和组织代码。
在Java中,使用 static 关键字修饰方法会使这个方法成为一个静态方法。静态方法不属于特定的实例,而是属于整个类,因此它可以在不创建类的实例的情况下直接通过类名调用。以下是关于使用 static 修饰方法的一些重要点:
-
静态方法声明: 静态方法必须在类的顶层声明,即在类的成员方法部分,但在构造方法之外。它们必须使用
static关键字修饰。 -
调用方式: 静态方法可以通过类名直接调用,不需要创建对象。例如,
ClassName.staticMethod()。 -
不能访问实例变量: 静态方法不能直接访问实例变量和非静态方法,因为它们不属于具体的实例。只能访问静态变量和静态方法。
-
不能被重写: 静态方法不能被子类重写(覆盖),因为它们属于类而不是实例,不具有多态性。
-
可以访问静态成员: 静态方法可以访问类中的其他静态成员,包括静态变量和其他静态方法。
下面是一个使用静态方法的例子:
public class Example {// 静态变量static int count = 0;// 静态方法public static void incrementCount() {count++;}// 非静态方法public void printCount() {System.out.println("Count: " + count);}public static void main(String[] args) {Example.incrementCount();Example.incrementCount();Example.printCount(); // 错误,静态方法无法访问实例方法}
}
在这个例子中,incrementCount 是一个静态方法,用于递增静态变量 count。由于它是静态的,可以通过类名直接调用。printCount 是一个非静态方法,无法在静态方法中直接访问,所以在 main 方法中调用它会导致错误。
静态的main方法
在Java中,
main方法必须是静态的,否则程序无法运行。这是因为在Java程序启动时,首先会加载类并调用静态的main方法作为程序的入口点。要使Java程序能够作为可执行程序运行,
main方法必须满足以下条件:
main方法必须是public访问修饰符,这样JVM才能访问它。main方法的返回类型必须是void,即不返回任何值。main方法的名称必须是main。main方法的参数必须是一个String数组(String[] args),用于接收命令行参数。另外,由于程序启动时没有创建对象,所以
main方法必须是静态的,以便可以通过类名直接调用,而不需要创建类的实例。以下是一个标准的
main方法的示例:public class MainExample {public static void main(String[] args) {System.out.println("Hello, Java!");} }在这个例子中,
main方法是一个静态方法,因此可以通过类名MainExample直接调用。运行这个程序时,JVM会从main方法开始执行,输出 “Hello, Java!”。
3.3 修饰代码块
在Java中,static 关键字不仅可以用于修饰静态变量和静态方法,还可以用于修饰静态代码块。静态代码块是一个特殊的代码块,在类加载时执行,用于进行一些类级别的初始化操作。以下是关于静态代码块的一些重要点:
-
静态代码块声明: 静态代码块是在类的成员部分,但在方法和构造方法之外声明的。它使用
static关键字修饰。 -
执行时机: 静态代码块在类加载时执行,只会执行一次,且在类的构造方法之前执行。
-
初始化操作: 静态代码块通常用于执行一些类级别的初始化操作,如初始化静态变量、加载资源等。
-
无法访问实例成员: 静态代码块不能直接访问实例变量和实例方法,因为它在类加载时执行,没有创建对象。
-
可以访问静态成员: 静态代码块可以访问类中的其他静态成员,包括静态变量和静态方法。
下面是一个使用静态代码块的例子:
public class StaticBlockExample {// 静态变量static int count;// 静态代码块static {count = 10;System.out.println("Static block initialized.");}public static void main(String[] args) {System.out.println("Count: " + count); // 输出:Count: 10}
}
在这个例子中,静态代码块用于初始化静态变量 count,并输出一条初始化信息。当类加载时,静态代码块会执行一次,然后在 main 方法中输出 count 的值。需要注意的是,静态代码块在类加载时自动执行,不需要显式调用。
静态代码块意义
静态代码块在Java中具有重要的意义,它主要用于在类加载时进行一些初始化操作,实现了以下几个方面的功能:
-
静态成员初始化: 静态代码块是在类加载时执行的,因此可以用于初始化静态变量。这对于需要进行一些计算、设置默认值或者加载静态资源的静态变量是非常有用的。
-
资源加载: 如果一个类需要加载一些外部资源,如配置文件、数据库连接等,静态代码块可以用来加载这些资源。这样可以确保在类第一次被使用时就完成资源的加载。
-
单次初始化: 静态代码块在类加载时只会执行一次,这意味着其中的初始化操作也只会执行一次。这对于需要确保某些初始化操作只执行一次的情况非常有用。
-
提高效率: 如果某些计算或操作在每个实例中都是相同的,将其放在静态代码块中可以减少重复计算,从而提高效率。
-
复杂初始化: 静态代码块可以用于执行一些较为复杂的初始化操作,这些操作可能无法在变量声明时完成。
下面是一个使用静态代码块初始化数据库连接的示例:
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class DatabaseConnection {static Connection connection;static {try {// 初始化数据库连接connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "username", "password");System.out.println("Database connection initialized.");} catch (SQLException e) {System.err.println("Database connection failed: " + e.getMessage());}}public static Connection getConnection() {return connection;}public static void main(String[] args) {Connection conn = DatabaseConnection.getConnection();// 使用数据库连接执行操作}
}
在这个例子中,静态代码块被用来初始化数据库连接,确保在类加载时连接已经建立,从而可以在其他地方使用这个连接。这种方式能够避免在每次需要连接数据库时都进行重复的初始化操作。
3.4 修饰内部类
在Java中,static 关键字可以用于修饰内部类,创建静态内部类。静态内部类与非静态内部类之间有一些重要的区别,主要体现在内部类的访问方式、生命周期和作用域等方面。
以下是关于使用 static 修饰内部类的一些重要点:
-
访问方式: 静态内部类可以直接通过外部类访问,无需创建外部类的实例。非静态内部类需要通过外部类的实例来访问。
-
生命周期: 静态内部类的生命周期与外部类无关,它的创建不依赖于外部类的实例。非静态内部类的生命周期与外部类实例的生命周期紧密关联。
-
作用域: 静态内部类可以在外部类的静态方法中直接使用,因为它们不依赖于外部类的实例。非静态内部类不能直接在外部类的静态方法中使用,因为它们需要通过外部类的实例来访问。
-
对外部类成员的访问: 静态内部类可以访问外部类的静态成员,但不能直接访问外部类的非静态成员。非静态内部类可以访问外部类的所有成员,包括静态和非静态。
以下是一个使用静态内部类的示例:
public class OuterClass {private static int outerStaticField = 10;private int outerInstanceField = 20;// 静态内部类public static class StaticInnerClass {public void printOuterFields() {System.out.println("Outer static field: " + outerStaticField);// 无法访问 outerInstanceField}}public static void main(String[] args) {StaticInnerClass inner = new StaticInnerClass();inner.printOuterFields();}
}
在这个例子中,StaticInnerClass 是一个静态内部类。在 main 方法中,我们创建了 StaticInnerClass 的实例,并通过它访问了外部类的静态成员 outerStaticField。需要注意的是,静态内部类不能直接访问外部类的非静态成员 outerInstanceField。
总之,静态内部类是与外部类分开的独立实体,无需外部类实例即可访问,因此在某些场景下可以提供更好的灵活性和封装性。
4、this关键字
在Java中,this 关键字用于引用当前对象,即正在执行代码的实例对象。它在访问类的成员变量、方法和构造方法时非常有用,以便明确指示正在操作的对象。以下是 this 关键字的几个主要作用:
-
引用当前对象: 在类的方法中,使用
this关键字引用当前对象,以便访问对象的成员变量和方法。 -
区分参数和成员变量: 如果方法的参数名与对象的成员变量名相同,使用
this关键字可以明确指示要访问的是成员变量而不是参数。 -
在构造方法中调用其他构造方法: 当一个类有多个构造方法时,可以使用
this关键字调用其他构造方法,以避免代码重复。 -
返回当前对象: 在方法中返回当前对象本身,以支持链式调用的编程风格。
以下是这些用法的示例:
public class Person {private String name;public Person(String name) {this.name = name; // 使用 this 关键字区分参数和成员变量}public void setName(String name) {this.name = name; // 使用 this 关键字引用当前对象的成员变量}public void printName() {System.out.println("Name: " + this.name);}public Person anotherPerson() {return this; // 返回当前对象本身}public static void main(String[] args) {Person person1 = new Person("Alice");Person person2 = new Person("Bob");person1.printName();person2.printName();person1.anotherPerson().printName(); // 链式调用}
}
在这个例子中,this 关键字用于引用当前对象,以区分参数和成员变量、调用方法以及返回当前对象本身。这有助于确保代码的清晰性和准确性。
5、封装特性
封装(Encapsulation)是面向对象编程(OOP)中的一种重要特性,它指的是将数据(成员变量)和操作数据的方法(成员方法)封装在一个类中,并通过访问修饰符来控制对这些数据和方法的访问。封装旨在实现数据隐藏、保护数据完整性,以及提供更好的抽象和封装性。
5.1 访问修饰符
Java的封装特性通过访问修饰符实现,主要有三种访问修饰符:private、protected 和 public。以下是封装特性的一些重要优点和原则:
-
数据隐藏: 封装允许将数据隐藏在类的内部,只暴露必要的接口供外部使用。这样可以避免直接访问数据,减少了错误和数据损坏的可能性。
-
数据完整性: 通过封装,可以限制对数据的访问方式,确保只有经过验证的方法可以修改数据。这有助于保持数据的正确性和一致性。
-
抽象: 封装使得类的外部使用者只需关心类的公共接口,而不需要了解内部实现细节。这促进了抽象和模块化编程。
-
灵活性: 封装允许在不影响外部代码的情况下修改类的内部实现。只要类的接口保持不变,类的实现可以进行改进。
-
维护性: 封装提高了代码的可维护性,因为修改类的内部实现不会影响使用该类的其他代码。
以下是一个使用封装的示例:
public class BankAccount {private String accountNumber;private double balance;public BankAccount(String accountNumber, double initialBalance) {this.accountNumber = accountNumber;this.balance = initialBalance;}public double getBalance() {return balance;}public void deposit(double amount) {if (amount > 0) {balance += amount;}}public void withdraw(double amount) {if (amount > 0 && amount <= balance) {balance -= amount;}}public static void main(String[] args) {BankAccount account = new BankAccount("123456", 1000.0);System.out.println("Initial balance: " + account.getBalance());account.deposit(500.0);System.out.println("After deposit: " + account.getBalance());account.withdraw(200.0);System.out.println("After withdrawal: " + account.getBalance());}
}
在这个例子中,BankAccount 类将成员变量 accountNumber 和 balance 封装在内部,并通过 public 方法来提供访问。外部代码只能通过这些方法来修改和访问数据,而无法直接访问内部数据。这样可以确保数据的安全性和正确性。
5.2 包的概念
在Java中,“包”(Package)是一种用于组织和管理类和接口的方式。包是一种逻辑上的组织结构,可以将相关的类和接口组织在一起,从而实现更好的模块化、代码复用和命名空间管理。每个类都必须属于一个包,除非它位于默认包中。
以下是关于Java包的一些重要概念:
-
命名空间管理: 包在Java中用于创建命名空间,防止类名冲突。如果不使用包,可能会在不同的库或项目中出现相同的类名,导致命名冲突。
-
包的层次结构: 包可以嵌套形成层次结构。例如,
java.util包是java包的子包,java.util.ArrayList类位于java.util包中。 -
包的声明: 在类文件的开头,使用
package关键字声明类所属的包。例如,package com.example;声明了类属于com.example包。 -
包的导入: 使用
import关键字可以引入其他包中的类,以便在当前类中使用。例如,import java.util.ArrayList;导入了java.util包中的ArrayList类。 -
默认包: 如果不在类文件中使用
package声明,则类被认为属于默认包。默认包是没有命名空间的,因此不建议在实际项目中使用。 -
约定: 包名通常使用小写字母,采用逆域名(反转的域名)的命名方式,以确保唯一性和清晰性。例如,
com.example.myproject。
以下是一个简单的包使用示例:
假设有两个类:Person 和 Address。可以将它们组织到一个叫做 com.example.myproject 的包中。
在 Person.java 文件中:
package com.example.myproject;public class Person {// 类的定义
}
在 Address.java 文件中:
package com.example.myproject;public class Address {// 类的定义
}
这样,Person 和 Address 类就位于同一个包中,可以通过导入包的方式在其他类中使用它们。
和C/C++中的头文件有些相似。
6、构造方法
在Java中,构造方法(Constructor)是一种特殊类型的方法,用于创建和初始化对象。构造方法在对象被创建时自动调用,用于设置对象的初始状态,分配内存和执行必要的初始化操作。以下是构造方法的一些重要特点:
-
方法名与类名相同: 构造方法的方法名必须与类名完全相同,包括大小写。它没有返回类型,也不需要声明返回值。
-
没有返回值: 构造方法不需要返回值类型,因为它们的主要目的是初始化对象,而不是返回值。
-
自动调用: 构造方法在使用
new关键字创建对象时自动调用。每次创建对象时,都会调用构造方法一次。 -
重载: 类可以有多个构造方法,以满足不同的初始化需求。这称为构造方法的重载。
-
默认构造方法: 如果类没有显式定义构造方法,编译器会自动提供一个无参数的默认构造方法。如果类定义了任何构造方法,编译器将不再提供默认构造方法。
以下是一个示例,展示如何定义和使用构造方法:
public class Person {private String name;private int age;// 构造方法1:带参数的构造方法public Person(String name, int age) {this.name = name;this.age = age;}// 构造方法2:无参数的构造方法public Person() {this.name = "Unknown";this.age = 0;}// 成员方法public void introduce() {System.out.println("Name: " + name);System.out.println("Age: " + age);}public static void main(String[] args) {Person person1 = new Person("Alice", 25);Person person2 = new Person();person1.introduce();person2.introduce();}
}
在这个例子中,Person 类定义了两个构造方法:一个带参数的构造方法用于设置对象的初始状态,另一个无参数的构造方法用于提供默认值。通过 new 关键字创建对象时,会根据提供的参数选择合适的构造方法进行初始化。
7、代码块
7.1 普通代码块
在Java中,普通代码块(也称为局部代码块)是一种用于限定变量作用域和执行特定代码的代码块。普通代码块不同于方法和构造方法,它位于方法内部,可以在其中定义临时变量,这些变量只在代码块内部可见。
以下是关于普通代码块的一些重要特点:
-
作用域限定: 在普通代码块中定义的变量只在代码块内部可见。这有助于避免命名冲突和混淆。
-
临时变量: 普通代码块通常用于定义临时变量,这些变量在代码块执行完毕后会被销毁,不会影响到方法外部的代码。
-
变量生命周期: 普通代码块内部定义的变量的生命周期仅限于代码块的执行期间。一旦代码块执行完毕,变量将被销毁。
-
代码块嵌套: 可以在方法中嵌套多个普通代码块。内部代码块中的变量对外部代码块不可见,但外部代码块中的变量对内部代码块可见。
以下是一个使用普通代码块的示例:
public class LocalBlockExample {public static void main(String[] args) {int x = 10; // 外部变量System.out.println("Outside x: " + x);{int y = 20; // 内部代码块变量System.out.println("Inside y: " + y);System.out.println("Inside x: " + x); // 可以访问外部变量}// y 在这里不可见{int z = 30; // 另一个内部代码块变量System.out.println("Inside z: " + z);}// z 在这里不可见}
}
在这个例子中,我们在 main 方法中使用了两个普通代码块。内部代码块中的变量只在代码块内部可见,不会影响到外部的变量。这有助于限定变量的作用域,提高代码的可读性和维护性。
7.2 成员代码块
成员代码块(Instance Initializer Block)是在Java类中的一个代码块,用于在创建对象实例时执行初始化操作。它类似于构造方法,但与构造方法不同的是,成员代码块在每次创建对象时都会执行,而不是在特定的构造方法中执行。
以下是关于成员代码块的一些重要特点:
-
执行顺序: 成员代码块在每次创建对象时都会在构造方法之前执行。如果一个类有多个构造方法,它们都会共享同一个成员代码块。
-
共享初始化逻辑: 成员代码块允许在多个构造方法之间共享相同的初始化逻辑,从而避免代码重复。
-
可用性: 成员代码块可以在类的任何地方定义,不受方法的限制。它会在构造方法前执行,无论构造方法如何调用。
以下是一个使用成员代码块的示例:
public class InstanceInitializerExample {private int x;private int y;// 成员代码块{x = 10;y = 20;System.out.println("Instance initializer block executed.");}// 构造方法1public InstanceInitializerExample() {System.out.println("Constructor 1 called.");}// 构造方法2public InstanceInitializerExample(int x, int y) {this.x = x;this.y = y;System.out.println("Constructor 2 called.");}public void printValues() {System.out.println("x: " + x + ", y: " + y);}public static void main(String[] args) {InstanceInitializerExample obj1 = new InstanceInitializerExample();obj1.printValues();InstanceInitializerExample obj2 = new InstanceInitializerExample(30, 40);obj2.printValues();}
}
在这个例子中,InstanceInitializerExample 类使用成员代码块来初始化 x 和 y 成员变量。每次创建对象时,成员代码块都会在构造方法之前执行。这有助于确保对象的初始化逻辑在不同的构造方法中得到共享。
7.3 静态代码块
上边 3.3 static修饰代码块处已经讲过,就不再赘述
7.4 同步代码块
在以后Java多线程的学习中会介绍
相关文章:
【Java】对象与类
【Java】对象与类 文章目录 【Java】对象与类1、学习背景2、定义&使用2.1 创建类2.2 创建对象 3、static关键字3.1 修饰变量3.2 修饰方法3.3 修饰代码块3.4 修饰内部类 4、this关键字5、封装特性5.1 访问修饰符5.2 包的概念 6、构造方法7、代码块7.1 普通代码块7.2 成员代码…...
视频尺寸缩小,一键批量剪辑,轻松制作精简版
大家好!在视频剪辑中,有时我们需要将大尺寸的视频缩小,以适应特定的需求和平台要求。为了帮助您轻松制作精简版视频,我们推出了一款全新的工具——视频尺寸缩小批量剪辑软件!让您一键批量将视频尺寸缩小,轻…...
leetcode做题笔记94. 二叉树的中序遍历
给定一个二叉树的根节点 root ,返回 它的 中序 遍历 。 思路一:模拟题意 void inorder(struct TreeNode*root,int* ans,int *resSize) {if(!root){return ;}inorder(root->left,ans,resSize);ans[(*resSize)] root->val;inorder(root->right…...
UWB高精度人员定位系统源码,微服务+java+ spring boot+ vue+ mysql技术开发
工业物联网感知预警体系,大中小企业工业数字化转型需求的工业互联网平台 工厂人员定位系统是指能够对工厂中的人员、车辆、设备等进行定位,实现对人员和车辆的实时监控与调度的系统,是智慧工厂建设中必不可少的一环。由于工厂的工作环境比较…...
企业党建杂志企业党建杂志社企业党建编辑部2023年第4期目录
卷首语 坚持学思用贯通 知信行统一 (0001) 赵荣地 国企与国资《企业党建》投稿:cn7kantougao163.com 深入推进新时代党的建设的重大部署 (0004) 陈锋 国有企业推进中国式现代化建设的使命任务和实践路径 (0006) 蒋雪群 创新与实践 浅析国企党建与生产经营工作…...
ChatGPT + Flutter快速开发多端聊天机器人App
下载地址:ChatGPT Flutter快速开发多端聊天机器人App 下载地址:ChatGPT Flutter快速开发多端聊天机器人App...
ubuntu18.04复现yolo v8之最终章,realsenseD435i+yolo v8完美运行
背景:上一篇博客我们已经为复现yolov8配置好了环境,如果前面的工作顺利进行,我们已经完成了90%(学习类程序最难的是环境配置)。 接下来将正式下载yolov8的相关代码,以及进行realsenseD435i相机yolo v8的de…...
Python统计中文词频的四种方法
统计中文词频是Python考试中常见的操作,由于考察内容较多,因此比较麻烦,那么有没有好的方法来实现呢?今天,我们总结了四种常见的中文词频统计方法,并列出代码,供大家学习参考。 中文词频统计主…...
sql server 快速安装
目录标题 一、下载二、直接选择基本安装二、下载ssms(数据库图形化操作页面)三、开启sa账号认证(一)第一步:更改身份验证模式(二)第二步:启用 sa 登录四、开启tcp/ip 一、下载 下载…...
机器学习之损失函数
深度学习中常用的损失函数多种多样,具体选择取决于任务类型和问题的性质。以下是一些常见的深度学习任务和相应的常用损失函数: 分类任务: 交叉熵损失函数(Cross-Entropy Loss):用于二分类和多类别分类任务…...
nacos适配SqlServer、Oracle
继上文《nacos适配达梦、瀚高、人大金仓数据库及部分源码探究 》后补充nacos适配SqlServer、Oracle的贴码,主要区别是SqlServer、Oracle的分页SQL有点不一样,做个记录; SqlServer的分页有三种实现方式:offset /fetch next、利用ma…...
力扣:74. 搜索二维矩阵(Python3)
题目: 给你一个满足下述两条属性的 m x n 整数矩阵: 每行中的整数从左到右按非递减顺序排列。每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target ,如果 target 在矩阵中,返回 true ;否则,返…...
CPU、MCU、MPU、SOC、SOCPC、概念解释之在嵌入式领域常听到的名词含义
CPU、MCU、MPU、SOC等几个在嵌入式领域学习过程中会涉及到的几个名词。我们来学习一下,资料从网上搜集的,有错的地方可以指出。。。 CPU、MCU、MPU、SOC、SOCPC、 1. CPU2. MPU3.MCUMPU和MCU的区别:4.SOC5. SoPC 1. CPU CPU,即中…...
每日两题 111二叉树的最小深度 112路径总和(递归)
111 题目 给定一个二叉树,找出其最小深度。 最小深度是从根节点到最近叶子节点的最短路径上的节点数量。 说明:叶子节点是指没有子节点的节点。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:2示例 2&#x…...
实训笔记8.24
实训笔记8.24 8.24笔记一、Sqoop数据迁移工具1.1 Sqoop的基本概念1.2 Sqoop的基本操作1.2.1 命令语法1.2.2 list-databases1.2.3 list-tables1.2.3 eval1.2.4 import1.2.5 export1.2.6 导入 二、Flume日志采集工具2.1 数据采集的问题2.2 数据采集一般使用的技术2.3 扩展&#x…...
Linux下的系统编程——系统调用(五)
前言: 由操作系统实现并提供给外部应用程序的编程接口。(Application Programming Interface,API)。系统调用就是应用程序同系统之间数据交互的桥梁。 open/close函数 1.open函数: (1)int open(char *pathname, int flags) …...
动物体外受精手术VR模拟仿真培训系统保证学生及标本的安全
奶牛是养殖业主要的资源,因此保证奶牛的健康对养殖业的成功和可持续发展具有重要已用,奶牛有一些常见易发病,一旦处理不当,对奶牛业都会造成较大的经济损失,传统的奶牛手术培训实操难度大、风险高且花费大,…...
微信小程序|步骤条
步骤条是现代用户界面设计中常见的元素之一,它能够引导用户按照预定顺序完成一系列任务或步骤。在小程序中,实现步骤条可以为用户提供更好的导航和引导,使用户体验更加流畅和直观。本文将介绍如何在小程序中实现步骤条,并逐步展示实现的过程和关键技巧 目录 步骤条的作用及…...
如何才能设计出“好的”测试用例?
软件测试用例的设计质量直接影响到测试的完整性、有效性以及自动化测试的实施效果,是软件测试成功的重要保证,良好的软件测试用例对于提高测试的有效性和效率至关重要。那大家知道好的测试用例该怎么写吗?应该从哪几个方面来撰写呢࿱…...
DirectExchange直连交换机
目录 一、简介 二、使用步骤 三、demo 父pom文件 pom文件 配置文件 config 消费者 生产者 测试 一、简介 直连型交换机,根据消息携带的路由键将消息投递给对应队列。 大致流程,有一个队列绑定到一个直连交换机上,同时赋予一个路由…...
树莓派超全系列教程文档--(62)使用rpicam-app通过网络流式传输视频
使用rpicam-app通过网络流式传输视频 使用 rpicam-app 通过网络流式传输视频UDPTCPRTSPlibavGStreamerRTPlibcamerasrc GStreamer 元素 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 使用 rpicam-app 通过网络流式传输视频 本节介绍来自 rpica…...
8k长序列建模,蛋白质语言模型Prot42仅利用目标蛋白序列即可生成高亲和力结合剂
蛋白质结合剂(如抗体、抑制肽)在疾病诊断、成像分析及靶向药物递送等关键场景中发挥着不可替代的作用。传统上,高特异性蛋白质结合剂的开发高度依赖噬菌体展示、定向进化等实验技术,但这类方法普遍面临资源消耗巨大、研发周期冗长…...
c++ 面试题(1)-----深度优先搜索(DFS)实现
操作系统:ubuntu22.04 IDE:Visual Studio Code 编程语言:C11 题目描述 地上有一个 m 行 n 列的方格,从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子,但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...
macOS多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用
文章目录 问题现象问题原因解决办法 问题现象 macOS启动台(Launchpad)多出来了:Google云端硬盘、YouTube、表格、幻灯片、Gmail、Google文档等应用。 问题原因 很明显,都是Google家的办公全家桶。这些应用并不是通过独立安装的…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
EtherNet/IP转DeviceNet协议网关详解
一,设备主要功能 疆鸿智能JH-DVN-EIP本产品是自主研发的一款EtherNet/IP从站功能的通讯网关。该产品主要功能是连接DeviceNet总线和EtherNet/IP网络,本网关连接到EtherNet/IP总线中做为从站使用,连接到DeviceNet总线中做为从站使用。 在自动…...
JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案
JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停 1. 安全点(Safepoint)阻塞 现象:JVM暂停但无GC日志,日志显示No GCs detected。原因:JVM等待所有线程进入安全点(如…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
使用 SymPy 进行向量和矩阵的高级操作
在科学计算和工程领域,向量和矩阵操作是解决问题的核心技能之一。Python 的 SymPy 库提供了强大的符号计算功能,能够高效地处理向量和矩阵的各种操作。本文将深入探讨如何使用 SymPy 进行向量和矩阵的创建、合并以及维度拓展等操作,并通过具体…...
