harMember = " +
Character.codePointAt( new char[] { charMember }, 0 ) );
System.out.println( "floatMember = " + floatMember );
System.out.println( "doubleMember = " + doubleMember );
System.out.println( "referenceMember = " + referenceMember );
}
}
一旦使用new关键字实例化:
inal InitializationWithDefaults initializationWithDefaults = new InitializationWithDefaults();
将会在控制台输出如下结果:
booleanMember = false
byteMember = 0
shortMember = 0
intMember = 0
longMember = 0
charMember = 0
floatMember = 0.0
doubleMember = 0.0
referenceMember = null
2.6 可见性(Visibility)
构造器受Java可见性规则约束并且可以拥有访问控制修饰符来决定是否其他类可以调用特定的构造函数。
2.7 垃圾回收(Garbage collection)
Java(特别是JVM)使用自动垃圾回收机制。简而言之,当新对象被创建,JVM就会自动为这些新创建的对象分配内存。于是,当这些对象没有任何引用的时候,他们就会被销毁并且他们所占用的内存就会被回收。
Java垃圾回收是分代的,基于这种假设(分代假设)大多数的对象在很年轻的时候就已经不可达(在他们被创建之后的很短的时间内就没有任何引用并且被安全销毁)。大多数开发者曾经相信在Java中创建对象是很慢的并且应该尽可能地避免新对象的实例化。
实际上,这并不成立:在Java中创建对象的开销非常的小并且很快。虽然如此,但是没有必要创建生命周期比较长的对象,因为创建过多的长寿命对象最终可能会填满老年代空间从而引发stop-the-world的垃圾回收,这样的话开销就会比较大。
2.8 终结器(Finalizers)
到目前为止,我们已经谈到了构造函数和对象初始化,但实际上并没有提到任何关于对象销毁的内容。这是因为Java使用垃圾收集器去管理对象的生命周期,并且垃圾收集器的责任就是去销毁无用对象并回收这些对象占用的内存。
然而,在Java中有一个被称为终结器(Finalizers)的特殊特性,它有点类似于析构函数,但是在执行资源清理时它所解决的是不同的意图。终结器(Finalizers)是被考虑用来解决一些危险的特征(比如会导致无数的副作用和性能问题的问题)。
一般来说,他们是没有必要的,应该避免(除了非常罕见的情况下,主要是有关本地对象)。Java 7语言引入了一种名为try-with-resources的更好的替代方法和AutoCloseable接口,它允许像如下的方式这样干净的写代码:
try ( final InputStream in = Files.newInputStream( path ) ) {
// code here
}
3、静态初始化(Static initialization)
到目前为止,,我们已经谈到了构造函数和对象初始化。但是Java也支持类级别的初始化构造,我们称之为静态初始化(Static initialization)。
静态初始化(Static initialization)有点类似于初始化块,除了需要添加static关键字之外。注意静态初始化在每次类加载的时候它只执行一次。比如:
package com.javacodegeeks.advanced.construction;
public class StaticInitializationBlock {
static {
// static initialization code here
}
}
和初始化块类似,在类定义时你可以包含任意数量的初始化块,它们会根据在类代码中出现的顺序依次执行,比如:
package com.javacodegeeks.advanced.construction;
public class StaticInitializationBlocks {
static {
// static initialization code here
}
static {
// static initialization code here
}
}
因为静态初始化(Static initialization)块可以从多个并行线程中触发(第一次类加载发生),Java运行时保证在线程安全的前提下仅仅被执行一次。
4、构造模式(Construction Patterns)
过去这几年很多易于理解和广泛应用的构造模式在Java社区出现。我们将会介绍几个比较常用的:单例模式(singleton)、帮助器(helpers)、工厂模式(factory)、依赖注入(dependency injection )——大家熟知的控制反转(inversion of control)。
4.1 单例模式(Singleton)
单例模式是软件开发者社区中最老也是最具争议性的模式之一。基本来说,它的主要思想就是确保在任何时候类仅仅只有一个实例被创建。思想就是如此简单,然而单例模式引发了很多关于如何使之正确的讨论,特别是线程安全的讨论。下面是单例模式原生版本的例子:
package com.javacodegeeks.advanced.construction.patterns;
public class NaiveSingleton {
private static NaiveSingleton instance;
private NaiveSingleton() {
}
public static NaiveSingleton getInstance() {
if( instance == null ) {
instance = new NaiveSingleton();
}
return instance;
}
}
这段代码至少有一个问题就是如果多个线程同时调用,那么此类就能够创建多个实例。设计合适的单例模式的方法之一是使用类的 static final属性。
final property of the class.
package com.javacodegeeks.advanced.construction.patterns;
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
如果你不想浪费资源并且希望在单例对象真正需要的时候才被延迟创建的话,这就要求显示同步了(explicit synchronization),这就有可能导致多线程环境中的并发性降低(