欢迎大家来到IT世界,在知识的湖畔探索吧!
原文:
前面已经介绍过两种初始化实例字段的方法:
- 在构造器中设置值
- 在声明中赋值
实际上,Java中还有第三种机制,称为初始化块(initialization block)。在一个类的声明中,可以包含任意的代码块。构造这个类的 对象时,这些块就会执行。例如。
class Employee47{
private static int nextId;
private int id;
private String name;
private double salary;
// object initialization block
{
id = nextId;
nextId ++;
}
public Employee47(String n,double s){
name =n;
salary = s;
}
public Employee47(){
name = "";
salary = 0;
}
// ...
}
欢迎大家来到IT世界,在知识的湖畔探索吧!
在这个示例中,无论使用哪个构造器构造对象,id字段都会在对象初始化块中初始化。首先运行初始化块,然后才运行构造器的主体部分。
这种机制不是必需的,也不常见。通常会直接将初始化代码块放在构造器中。
注释:可以在初始化块中设置字段,即使这些字段在类后面才定义,这是合法的。但是,为了避免循环定义,不允许读取在后面初始化的字段。具体规则请参见Java语法规范的8.3.3 节(https://docs.oracle.com/javase/specs/)。这些规则太过复杂,让编译器实现者都头疼,所以较早的Java版本中这些规则的实现存在一些小错误。因此,建议总是将初始化块放在字段定义之后。
由于初始化实例字段有多种途径,所以列出构造过程的所有路径可能让人很费解。下面是调用构造器时的具体处理步骤:
- 如果构造器的第一行调用了另一个构造器,则基于所提供的参数执行第二个构造器。
- 否则,
- 所有实例字段初始化为其默认值(0 ,false 或 null)
- 按照在类声明中出现的顺序,执行所有字段初始化方法和初始化块。
- 执行构造器主体代码
- 当然,最好精心地组织初始化代码,以便其他程序员轻松理解,而不要求他们都是语言专家。例如,如果让类的构造器依赖于实例字段声明的顺序,那么就会显得很奇怪并且容易引起错误。可以通过提供一个初始值,或者使用一个静态的初始化块来初始化静态字段。前面已经介绍过第一种机制:private static int nextId = 1;如果类的静态字段需要很复杂的初始化代码,那么可以使用静态的初始化块。将代码放在一个块中,并标记关键字static 。下面是一个示例。我们希望将员工ID的起始值赋值为一个小于10000的随机整数。private static Random generator =new Random();// static initialization blockstatic{ nextId = generator.nextInt(10000);}在类第一次加载的时候,会完成静态字段的初始化。与实例字段一样,除非将静态字段显式地设置为其他值,否则默认的初始值为0、false 或null。所有的静态字段初始化方法以及静态初始化块都将依照类生命中出现的顺序执行。注释:让人惊讶的是,在JDK6之前,完全可以用Java编写一个没有main方法的”hello world” 程序。public class Hello{ static { System.out.println(“Hello world”); }
}当用java Hello 调用这个类时,就会加载这个类,静态初始化块将会打印”Hello World”。在此之后才会显示一个消息指出main方法未定义。从Java 7以后,Java程序会首先检查是否有一个main方法。这个例子使用了Random 类来生成随机数。从JDK17 开始,java.util.random包提供了考虑多种因素的强算法的实现。阅读java.util.random 包下的api文档,其中对如何选择算法给出了建议。然后通过提供算法名来得到一个实例,如下所示:RandomGenerator generator = RandomGenerator.of(“L64X128MixRandom”);调用 generator.nextInt(n) 或其他 RandomGenerator 方法来生成随机数。(RandomGenerator 是一个接口,第6章将讲述接口概念。Random类的对象可以使用所有RandomGenerator 方法)程序清单4-5 中的程序展示了本书讨论的很多特性: - 重载构造器
- 用this(…) 调用另一个构造器
- 无参数构造器
- 对象初始化块
- 静态初始化块
- 实例字段初始化
程序清单4-5 ConstructorTest.java
欢迎大家来到IT世界,在知识的湖畔探索吧!import java.util.*;
/**
* This program demonstrates object construction.
* @version 1.02 2018-04-10
* @author Cay Horstmann
*/
public class ConstructorTest
{
public static void main(String[] args)
{
// fill the staff array with three Employee objects
var staff = new Employee[3];
staff[0] = new Employee("Harry", 40000);
staff[1] = new Employee(60000);
staff[2] = new Employee();
// print out information about all Employee objects
for (Employee e : staff)
System.out.println("name=" + e.getName() + ",id=" + e.getId() + ",salary="
+ e.getSalary());
}
}
class Employee
{
private static int nextId;
private int id;
private String name = ""; // instance field initialization
private double salary;
private static Random generator = new Random();
// static initialization block
static
{
// set nextId to a random number between 0 and 9999
nextId = generator.nextInt(10000);
}
// object initialization block
{
id = nextId;
nextId++;
}
// three overloaded constructors
public Employee(String n, double s)
{
name = n;
salary = s;
}
public Employee(double s)
{
// calls the Employee(String, double) constructor
this("Employee #" + nextId, s);
}
// the default constructor
public Employee()
{
// name initialized to ""--see above
// salary not explicitly set--initialized to 0
// id initialized in initialization block
}
public String getName()
{
return name;
}
public double getSalary()
{
return salary;
}
public int getId()
{
return id;
}
}
API java.util.Random 1.0
- Random() 构造一个新的随机数生成器
java.util.random.RandomGenerator 17
- int nextInt(int n)
- static RandomGenerator of(String name)
- 由给定算法名生成一个随机数生成器。算法”L64X128MixRandom”对大多数应用都适用。
免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://itzsg.com/34844.html