Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/315.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何在初始化类之前设置字段值?_Java_Class_In Class Initialization - Fatal编程技术网

Java 如何在初始化类之前设置字段值?

Java 如何在初始化类之前设置字段值?,java,class,in-class-initialization,Java,Class,In Class Initialization,我正在阅读关于java.sql.DriverManager的源代码,发现一些令人困惑的地方。以下是代码: static { loadInitialDrivers(); println("JDBC DriverManager initialized"); } ...... public static void println(String message) { synchronized (logSync) { if (logWriter != null) {

我正在阅读关于java.sql.DriverManager的源代码,发现一些令人困惑的地方。以下是代码:

static {
    loadInitialDrivers();
    println("JDBC DriverManager initialized");
}
......
public static void println(String message) {
    synchronized (logSync) {
        if (logWriter != null) {
            logWriter.println(message);

            // automatic flushing is never enabled, so we must do it ourselves
            logWriter.flush();
        }
    }
}
在类初始化时没有设置logWriter,但是被它的静态块调用了。所以我看不到任何关于这个的日志信息。
如何在类初始化之前设置字段值?

唯一的方法是在
驱动程序
实现中设置
日志编写器

public class MyDriver implements Driver {

  static {
    // DriverManager will use ServiceLoader to load this class
    DriverManager.setLogWriter(new PrintWriter(System.out));
  }

  ... all methods in Driver
}
然后你会得到日志

DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
编辑 对于@moilejter的问题,这里给出一个简单的示例,说明两个类如何相互调用,即使它们都没有准备好

public class JustTest {
  public static void main(String[] args) throws java.lang.Exception {
    A.i = 2;
  }
}

class A {
  static int i = 1;
  static {
    System.out.println("a block start");
    B.print();
  }

  public static void print() {
    System.out.println("a print: " + B.i);
  }
}

class B {
  static int i = 1;
  static {
    System.out.println("b block start");
    A.print();
  }

  public static void print() {
    System.out.println("b print: " + A.i);
  }
}

唯一的方法是在
驱动程序
实现中设置
日志编写器

public class MyDriver implements Driver {

  static {
    // DriverManager will use ServiceLoader to load this class
    DriverManager.setLogWriter(new PrintWriter(System.out));
  }

  ... all methods in Driver
}
然后你会得到日志

DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
编辑 对于@moilejter的问题,这里给出一个简单的示例,说明两个类如何相互调用,即使它们都没有准备好

public class JustTest {
  public static void main(String[] args) throws java.lang.Exception {
    A.i = 2;
  }
}

class A {
  static int i = 1;
  static {
    System.out.println("a block start");
    B.print();
  }

  public static void print() {
    System.out.println("a print: " + B.i);
  }
}

class B {
  static int i = 1;
  static {
    System.out.println("b block start");
    A.print();
  }

  public static void print() {
    System.out.println("b print: " + A.i);
  }
}

如果您使用
控制台
,则可以使用此代码:

DriverManager.setLogWriter(new PrintWriter(System.out));  

如果您使用
控制台
,则可以使用此代码:

DriverManager.setLogWriter(new PrintWriter(System.out));  

嗯-我没想到这会起作用,因为我认为调用setLogWriter()时对DriverManager的引用会迫使Java在调用setLogWriter()之前加载该类,而静态初始值设定项块会在加载该类时运行-所以,在调用setLogWriter之前…@moilejter不,你错了。类装入与类初始化不同。当
DriverManager
的静态块运行时,这意味着
DriverManager
已加载,因为尚未准备就绪。其他类可以访问所有已初始化的内容。这就是为什么静态块是在
logWriter
的定义下定义的。毕竟,自己做测试很容易。@moilejter我更新了我的答案,给你一个简单的例子。玩吧!对不起,你能给出一个完整的解决方案吗?我仍然不知道该怎么做。我只是写了一个新类,让它实现java.sql.Driver,然后我该怎么做?@DeanXu@JackZhou我认为你应该先学习
JavaSPI
。然后通过SPI方式提供
MyDriver
。我将在gist.Hmm中提供一个最小化的代码-我没有料到这会起作用,因为我认为调用setLogWriter()时对DriverManager的引用会迫使Java在调用setLogWriter()之前加载该类,而静态初始值设定项块会在加载该类时运行-因此,在你打电话给setLogWriter之前…@moilejter不,你错了。类装入与类初始化不同。当
DriverManager
的静态块运行时,这意味着
DriverManager
已加载,因为尚未准备就绪。其他类可以访问所有已初始化的内容。这就是为什么静态块是在
logWriter
的定义下定义的。毕竟,自己做测试很容易。@moilejter我更新了我的答案,给你一个简单的例子。玩吧!对不起,你能给出一个完整的解决方案吗?我仍然不知道该怎么做。我只是写了一个新类,让它实现java.sql.Driver,然后我该怎么做?@DeanXu@JackZhou我认为你应该先学习
JavaSPI
。然后通过SPI方式提供
MyDriver
。我将在gist中提供一个最小代码。谢谢,但它不起作用。我可以看到“JDBC DriverManager initialized”谢谢,但它不起作用。我可以看到“JDBC DriverManager initialized”