java使用静态代码块打印初始化数据
时间: 2023-12-18 21:04:53 浏览: 137
可以使用静态代码块来初始化数据并打印输出,示例如下:
```
public class Test {
static int a;
static String b;
static {
a = 10;
b = "Hello World";
System.out.println("a = " + a);
System.out.println("b = " + b);
}
public static void main(String[] args) {
// do something
}
}
```
在上面的示例代码中,静态代码块用于初始化静态变量a和b,并且在初始化完成后打印输出它们的值。当类被加载时,静态代码块会被执行,因此在执行main方法之前,变量a和b已经被初始化并打印输出了。
相关问题
java 类初始化顺序
### Java 类加载和初始化顺序
#### 一、类的加载与ClassLoader的理解
类的加载是指将类的 `.class` 文件中的二进制数据读入到内存中,并将其放在运行时的方法区之中,然后在堆区创建一个 `java.lang.Class` 对象,用来封装这些数据。这一过程由类加载器完成[^1]。
#### 二、什么时候会发生类初始化
当程序首次使用特定类或接口时,会触发该类或接口的初始化操作。具体来说:
- **类的主动引用**:一定会发生类的初始化的情况包括通过 `new` 关键字实例化对象;访问静态变量或调用静态方法;反射方式获取类的信息等。
- **类的被动调用**:不会引起类的初始化的情形有定义子类时不自动触发父类的初始化;通过数组定义类引用也不会触发此类的初始化;引用常量表达式的值(如基本类型的常量或字符串常量池中的字符串)也不引发类的初始化。
#### 三、类加载器的作用
类加载器负责查找并装载所需的类文件至 JVM 中。它遵循双亲委派模型原则工作,即先尝试让上级加载器去处理请求,在找不到对应资源的情况下才会自己继续寻找相应的类文件[^3]。
#### 四、动态创建对象执行方法
对于新创建的对象而言,除了要经历上述提到的一系列加载流程外,还需要按照一定的顺序来进行成员变量赋初值以及构造函数内的逻辑运算。这涉及到字段声明处赋予默认值/显式指定初始值的动作,还有可能存在的静态代码块与非静态代码块被执行的过程[^2]。
#### 五、成员初始化
成员变量可以在声明的同时给予初始值,也可以不给定任何初始值而采用系统的默认值。如果存在多个同名但不同作用域下的局部变量,则最内层的作用范围优先级最高[^4]。
#### 六、构造器初始化
每当创建一个新的对象实例时都会调用对应的构造器来设置一些必要的状态信息。需要注意的是,即使是没有显示写出无参构造器,默认情况下也会有一个隐含的存在着。
#### 七、初始化顺序
考虑下面的例子可以更好地理解整个初始化序列是如何工作的:
```java
// 定义两个类 A 和 B,其中 B 继承自 A
class A {
public static String sStaticField = "A's Static Field";
static {
System.out.println("Initializing Class A");
}
}
class B extends A {
public static String sSubClassField = "B's Sub-Class Field";
static {
System.out.println("Initializing Class B");
}
private int instanceVar;
{
this.instanceVar = 9;
System.out.println("Instance Block of B Executed.");
}
public B(){
super();
System.out.println("Constructor of B Called.");
}
}
```
在这个例子中,假设我们只执行了如下语句:
```java
public class Main{
public static void main(String[] args){
new B(); // 创建 B 的实例
}
}
```
那么输出将会是这样的:
```
Initializing Class A
Initializing Class B
Instance Block of B Executed.
Constructor of B Called.
```
这是因为首先会加载基类 `A` 并打印出 `"Initializing Class A"` ,接着再加载派生类 `B` 打印出 `"Initializing Class B"` 。之后是非静态代码块里的内容被执行,最后才是构造器被调用[^5]。
在一个student类中,我在static代码块中初始化一个student的集合students,并且这个集合不是类的属性,那么在主程序中,这个集合是否能被使用,而且能否不通过类调用直接使用这个集合
静态代码块是在类加载时执行的一段代码,这意味着它在创建类的实例之前就被执行了。如果你在`Student`类的静态代码块中初始化了一个名为`students`的集合,即使这个集合不是类的一个属性(即没有定义为`private static List<Student> students;`这样的成员变量),这个集合仍然会在类加载时存在。
在主程序中,你可以通过类名访问到这个静态集合,不需要创建类的实例就能直接使用。由于它是静态的,可以直接使用`Student.students`来引用这个集合。例如:
```java
public class Student {
// ...
static {
List<Student> students = new ArrayList<>();
// 初始化学生列表...
}
}
// 在主程序中
public static void main(String[] args) {
System.out.println(Student.students); // 直接打印集合内容
}
```
然而,请注意,虽然你可以这样做,但通常情况下,在静态代码块中创建并管理类级别的数据并不是最佳实践。因为这可能会导致难以理解和维护的代码结构,特别是在需要线程安全的情况下。如果需要频繁操作这个集合,可能更适合将其设计为类的一个静态属性或提供一个静态工厂方法返回该集合。
阅读全文
相关推荐
















