??xml version="1.0" encoding="utf-8" standalone="yes"?>
2:一个具体实?br />3:一个虚拟机实例
java虚拟机的生命周期
java虚拟机的天职是:q行一个javaE序.当一个javaE序q行开始运行时,一个虚拟机实例׃生了(jin).当一个计机上同时运行三个javaE序.则将产生三个java虚拟机实?每个E序q行在自q虚拟机里?不会(x)q扰.当程序运行完毕时,虚拟机将自动退?
java虚拟机里面有两种U程,守护U程和非守护U程.守护U程是说java虚拟qU程,如垃圾收集线E?而非守护U程则是java中运行的E序U程.当非守护U程都运行完?java虚拟机将退?
一个java虚拟Z要包括了(jin):c{载子pȝ,q行时数据区,执行引擎,内存区等{?
q行时数据区------主要?1 ?2 (tng) Ҏ(gu)?3 java?br />
堆和Ҏ(gu)区对虚拟机实例中所有的对象都是׃n?而java栈区,是对每个U程都是独立? 当一个class被蝲入到 classloader中时,?x)解析它的类型信?把这些类型信息放到方法区,而把E序中运行的对象,攑ֈ堆区.当一个新U程被创?分配一个新的java?java栈中保存?是方法中的一些变?状?java栈是由很多的java栈l成?一个栈帧包含了(jin)一个方法运行的状?当一个方法被执行的时?压入一个新的java栈到java栈中,Ҏ(gu)q回的时?把栈弹出?抛弃?
Ҏ(gu)?br />
在java虚拟Z,被装载的cȝcd信息和类的静(rn)态变量被存储在方法区q样的内存里?javaE序q行??x)查找这些个信?Ҏ(gu)区的大小,是动态的.也可以不是连l的.可自由在堆中分配.也可以由用户或者程序员指定.Ҏ(gu)区可被垃圾收?
Ҏ(gu)区可以保存以下信?br />q个cd的全限定?br />直接类的全限定?br />是类cdq是接口
cd的访问修饰符
M直接类接口的全限定名的有序列表.
该类型的帔R?br />字段信息 cM声明的每个字D及(qing)光?如字D名,cd.修饰W号.
Ҏ(gu)信息:如方法名,q回cd.参数表列.修饰W号.字节?操作数栈和栈帧中局部变量区大小{等
c静(rn)态变?br />一个到cclassloader的引?br />一个到classcȝ引用
?br />用来存储q行时的对象实例
java?br />每启动一个新的线E?׃(x)分配C个java?java栈以帧ؓ(f)单位保存U程的运行状?它有两种操作.入栈,出栈.
当一个方法被调用?入栈,当一个方法返回时,出栈,或者当Ҏ(gu)出现异常.也出?
栈
l成部分 局部变量区,操作数栈,帧数据区.
]]>
java中也要注意内存管?br />
// Can you spot the "memory leak"?
public class Stack {
private Object[] elements;
private int size = 0;
public Stack(int initialCapacity) {
this.elements = new Object[initialCapacity];
}
Effective Java: Programming Language Guide
17
public void push(Object e) {
ensureCapacity();
elements[size++] = e;
}
public Object pop() {
if (size == 0)
throw new EmptyStackException();
return elements[--size];
}
/**
* Ensure space for at least one more element, roughly
* doubling the capacity each time the array needs to grow.
*/
private void ensureCapacity() {
if (elements.length == size) {
Object[] oldElements = elements;
elements = new Object[2 * elements.length + 1];
System.arraycopy(oldElements, 0, elements, 0, size);
}
}
}
q里有一个内存泄?br />如果一个栈先是增长Q然后再收羃Q那么,从栈中弹出来的对象将不会(x)被当做垃圑֛Ӟ即使用栈的客户E序不再引用q些对象Q它们也不会(x)被回收。这是因为,栈内部维护着对这些对象的q期引用Qobsolete re f e re n c eQ。所谓过期引用,是指永远也不?x)再被解除的引?br />
Ҏ(gu)
public Object pop() {
if (size==0)
throw new EmptyStackException();
Object result = elements[--size];
elements[size] = null; // Eliminate obsolete reference清除引用
return result;
}
当程序员W一ơ被cMq样的问题困扰的时候,他们往往?x)过分小心(j)?x)对于每一个对象引用,一旦程序不再用到它Q就把它清空。这样做既没必要Q也不是我们所期望的,因ؓ(f)q样做会(x)把程序代码弄得很乱,q且可以惛_q会(x)降低E序的性能。“清I对象引用”这L(fng)操作应该是一U例外,而不是一U规范行为。消除过期引用最好的Ҏ(gu)是重用一个本来已l包含对象引用的变量Q或者让q个变量l束其生命周期。如果你是在最紧凑的作用域范围内定义每一个变量(见第2 9条)(j)Q则q种情Ş׃(x)自然而然地发生。应该注意到Q在目前的J V M实现q_上,仅仅退出定义变量的代码块是不够的,要想使引用消失,必须退出包含该变量的方法?br />
一般而言Q只要一个类自己理它的内存Q程序员应该警惕内存泄漏问题。一旦一个元素被释放掉,则该元素中包含的M对象引用应该要被清空?br />
内存泄漏的另一个常见来源是~存。一旦你把一个对象引用放C个缓存中Q它?yu)很?gu)被遗忘掉Q从而得它不再有用之后很长一D|间内仍然留在~存?br />
]]>
String s = new String("silly"); // DON'T DO THIS!
String s = "No longer silly";//do this
In addition to reusing immutable objects, you can also reuse mutable objects that you know will not be modified. Here is a slightly more subtle and much more common example of what not to do, involving mutable objects that are never modified once their values have been computed:
除了(jin)重用非可变的对象之外Q对于那些已知不?x)被修改的可变对象,你也可以重用它们?br />
such as
public class Person {
private final Date birthDate;
// Other fields omitted
public Person(Date birthDate) {
this.birthDate = birthDate;
}
// DON'T DO THIS!
public boolean isBabyBoomer() {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
Date boomStart = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
Date boomEnd = gmtCal.getTime();
return birthDate.compareTo(boomStart) >= 0 &&
birthDate.compareTo(boomEnd) < 0;
}
}
改良的版?
The isBabyBoomer method unnecessarily creates a new Calendar, TimeZone, and two Date instances each time it is invoked. The version that follows avoids this inefficiency with a static initializer:
class Person {
private final Date birthDate;
public Person(Date birthDate) {
this.birthDate = birthDate;
}
/**
* The starting and ending dates of the baby boom.
*/
private static final Date BOOM_START;
private static final Date BOOM_END;
static {
Calendar gmtCal =
Calendar.getInstance(TimeZone.getTimeZone("GMT"));
gmtCal.set(1946, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_START = gmtCal.getTime();
gmtCal.set(1965, Calendar.JANUARY, 1, 0, 0, 0);
BOOM_END = gmtCal.getTime();
}
public boolean isBabyBoomer() {
return birthDate.compareTo(BOOM_START) >= 0 &&
birthDate.compareTo(BOOM_END) < 0;
}
}
。一个适配器是指这样一个对象:(x)它把功能?br />托给后面的一个对象,从而ؓ(f)后面的对象提供一个可选的接口。由于适配器除?jin)后面的对象之外Q没有其他的状态信息,所以针Ҏ(gu)个给定对象的特定适配器而言Q它不需要创建多个适配器实例?br />
This item should not be misconstrued to imply that object creation is expensive and should be avoided. On the contrary, the creation and reclamation of small objects whose constructors do little explicit work is cheap, especially on modern JVM implementations. Creating additional objects to enhance the clarity, simplicity, or power of a program is generally a good thing.
Conversely, avoiding object creation by maintaining your own object pool is a bad idea unless the objects in the pool are extremely heavyweight. A prototypical example of an object that does justify an object pool is a database connection. The cost of establishing the connection is sufficiently high that it makes sense to reuse these objects. Generally speaking, however, maintaining your own object pools clutters up your code, increases memory footprint, and harms performance. Modern JVM implementations have highly optimized garbage collectors that easily outperform such object pools on lightweight objects.
]]>
Occasionally you'll want to write a class that is just a grouping of static methods and static fields.有时?你想写一个类,只是需要他提供?jin)一pd的函数操作等,而不惌它实例化.?java.lang.Math or java.util.Arrays.
但是如果你不提供构造函?~译器会(x)自动d一?
所以必L供一?此时,把构造函数设|ؓ(f)private.可以达到目?
一般用与工L(fng).
// Noninstantiable utility class
public class UtilityClass {
// Suppress default constructor for noninstantiability
private UtilityClass() {
// This constructor will never be invoked
}
... // Remainder omitted
}
׃private的构咱函?该类不能被实例化.同时.不能被承了(jin).
]]>
A singleton is simply a class that is instantiated exactly once [Gamma98, p. 127].如数据库资源{?
There are two approaches to implementing singletons. Both are based on keeping the
constructor private and providing a public static member to allow clients access to the sole
instance of the class. In one approach, the public static member is a final field:
// Singleton with final field
public class Elvis {
public static final Elvis INSTANCE = new Elvis();
private Elvis() {
...
}
... // Remainder omitted
}
1:构造函数私?br />2:提供一个静(rn)态static的final成员
The private constructor is called only once, to initialize the public static final field
Elvis.INSTANCE. (tng)
Exactly one Elvis instance will exist once the Elvis class is initialized—no more,
no less. Nothing that a client does can change this.
In a second approach, a public static factory method is provided instead of the public static final field:
// Singleton with static factory
public class Elvis {
private static final Elvis INSTANCE = new Elvis();
private Elvis() {
...
}
public static Elvis getInstance() {
return INSTANCE;
}
... // Remainder omitted
}
用静(rn)态方法返?而不是直接返回一个实?
如果对对象序列化,要做多一点工??br />To make a singleton class serializable (Chapter 10), it is not sufficient merely to add
implements Serializable to its declaration. To maintain the singleton guarantee, you must
also provide a readResolve method (Item 57). Otherwise, each deserialization of a serialized instance will result in the creation of a new instance, 否则,l过对象反序列化??x)导致创Z(jin)一个新的对?leading, in the case of our example, to spurious Elvis sightings. To prevent this, add the following readResolve method to the Elvis class:
// readResolve method to preserve singleton property
private Object readResolve() throws ObjectStreamException {
/*
* Return the one true Elvis and let the garbage collector
* take care of the Elvis impersonator.
*/
return INSTANCE;
}
]]>
constructors 考虑以静(rn)态工厂方法取代构造函?br />
The normal way for a class to allow a client to obtain an instance is to provide a public
constructor.
A class can provide a public static factory method, which is simply
a static method that returns an instance of the class
such as
public static Boolean valueOf(boolean b) {
return (b ? Boolean.TRUE : Boolean.FALSE);
}
advantages
1:One advantage of static factory methods is that, unlike constructors, they have names.
一个类?rn)态工厂方法是有名字的.If the parameters to a constructor do not, in and of themselves, describe the object being returned, a static factory with a well-chosen name can make a class easier to use and the resulting client code easier to read. 如BigInteger(int, int,Random)只知道new?jin)一个BigInteger对象,而BigInteger.probablePrime()能说明返回的可能是一个素数对?另外,如果一个构造函C仅由于参数顺序不同而意思也不同.?rn)态工厂方法就更加有用?它更能说明函数的意?因ؓ(f)它有一个名?
the reason (tng)are : If the parameters to a constructor do not, describe the object being
returned, a static factory with a well-chosen name can make a class easier to use and the
resulting client code easier to read.
2:A second advantage of static factory methods is that, unlike constructors, they are not
required to create a new object each time they're invoked.每次h?不需要重新创Z个对?---单例的意?q可以在M时刻控制q个对象,同时在比较的时候也不需要用equals而用= =可以解决了(jin).
3:A third advantage of static factory methods is that, unlike constructors, they can return
an object of any subtype of their return type.可以q回一个原q回cd的子cd对象.
One application of this flexibility is that an API can return objects without making their
classes public.Hiding implementation classes in this fashion can lead to a very compact API.q种灉|性的一个应用是Q一个A P I可以q回一个对象,同时又不使该对象的类成ؓ(f)公有的。以q种方式把具体的实现c隐藏v来,可以得到一个非常简z的A P I。这Ҏ(gu)术非帔R合
于基于接口的框架l构Q因为在q样的框架结构中Q接口成为静(rn)态工厂方法的自然q回cd
sample:
// Provider framework sketch
public abstract class Foo {
// Maps String key to corresponding Class object
private static Map implementations = null;
// Initializes implementations map the first time it's called
private static synchronized void initMapIfNecessary() {
if (implementations == null) {
implementations = new HashMap();
// Load implementation class names and keys from
// Properties file, translate names into Class
// objects using Class.forName and store mappings.
...
}
}
public static Foo getInstance(String key) {
initMapIfNecessary();
Class c = (Class) implementations.get(key);
if (c == null)
return new DefaultFoo();
try {
return (Foo) c.newInstance();
} catch (Exception e) {
return new DefaultFoo();
}
}
}
公有的静(rn)态工厂方法所q回的对象的cM仅可以是非公有的Q而且该类可以随着每次调用
而发生变化,q取决于?rn)态工厂方法的参数倹{只要是已声明的q回cd的子cdQ都是允
许的。而且Qؓ(f)?jin)增Y件的可维护性,q回对象的类也可以随着不同的发行版本而不同?br />disadvantages:
1:The main disadvantage of static factory methods is that classes without public or protected constructors cannot be subclassed.
cd果不含公有的或者受保护的构造函敎ͼ׃能被子类化。对于公有的?rn)态工厂所q回的非公有c,也同样如?br />
2:A second disadvantage of static factory methods is that they are not readily distinguishable from other static methods.
In summary, static factory methods and public constructors both have their uses, and it pays to understand their relative merits. Avoid the reflex to provide constructors without first considering static factories because static factories are often more appropriate. If you've weighed the two options and nothing pushes you strongly in either direction, it's probably best to provide a constructor simply because it's the norm.