Java FAQ 55--Special creation theory

Source: Internet
Author: User

Sometimes, for a class, it is very useful to keep track of the number of instances it creates, and its typical implementation is done by incrementing its constructor by a private static domain. In the following program, the creature class demonstrates this technique, and the creator class drills it to print out the number of creature instances that have been created. So, what does this program print?


<span style= "FONT-SIZE:18PX;" >public class Creator {public    static void Main (string[] args) {for        (int i = 0; i <; i++)            creature creature = new Creature ();        System.out.println (creature.numcreated ());}    } Class Creature {    private static long numcreated = 0;    Public creature () {        numcreated++;    }    public static long numcreated () {        return numcreated;    }} </span>


It's a matter of teasing people. The program looks like it should print 100, but it doesn't print anything because it doesn't compile at all. If you try to compile it, you'll find that the compiler's diagnostic information is basically useless. Here's what Javac prints:

<span style= "FONT-SIZE:18PX;" >creator.java:4: Not a statement            creature creature = new Creature ();            ^creator.java:4: '; ' expected            creature creature = new Creature ();                            ^</span>


A local variable declaration looks like a statement, but technically it is not; it should be a local variable declaration statement (local variable declaration statement) [JLS 14.4].

The Java language Specification does not allow a local variable declaration statement to be repeated in a for, while, or do loop as a statement [JLS 14.12-14]. a local variable declaration can only appear directly in a block of statements as a single statement. (a block of statements consists of a pair of curly braces and the statements and declarations contained in this flower-enclosed exhibition.) )
There are two ways to revise this question. The most obvious way to do this is to use this declaration as a block of statements:


<span style= "FONT-SIZE:18PX;" >for (int i = 0; i <; i++) {     creature creature = new Creature ();} </span>

Note, however, that the program does not use the local variable creature. Therefore, it would be more practical to replace the declaration with a constructor that does not have any adornments, which would emphasize that the reference to the newly created object is being discarded:
for (int i = 0; i <; i++)
New creature ();
Whichever of the above changes we make, the program will print out the 100 we expect.
Note that the variable (numcreated) that is used to track the number of creature instances is a long type and not an int type. It is easy to imagine that an instance of a class created by a program might be extra large for an int value, but it would not be more than the maximum value of a long value.
The maximum value of the int value is 231-1, which is approximately 2.1x109, and the maximum value of the Long value is 263-1, which is about 9.2x1018. Currently, it is possible to create 108 objects per second, which means that a program has to run for about 3,000 years before a long object counter overflows. Even in the face of hardware speed improvements, a long object counter should be sufficient to handle the foreseeable future.
Also note that the Create count policy in this puzzle is not thread-safe. If multiple threads can create objects in parallel, the code that increments the counter and the code that reads the counter should be synchronized:
<span style= "FONT-SIZE:18PX;" >//Thread-safe creation Counterclass creature {    private static long numcreated;    Public creature () {        synchronized (creature.class) {            numcreated++;        }    }    public static synchronized Long numcreated () {        return numcreated;    }} </span>


Or, if you're using a 5.0 or later version, you can use a Atomiclong instance that bypasses the need for synchronization when faced with concurrency.
<span style= "FONT-SIZE:18PX;" >//Thread-safe creation counter using Atomiclong;import java.util.concurrent.atomic.atomiclong;class Creature {    private static Atomiclong numcreated = new Atomiclong ();    Public creature () {        numcreated.incrementandget ();    }    public static long numcreated () {        return numcreated.get ();}    } </span>


Note that declaring numcreated as instantaneous is not enough to solve the problem, because the volatile modifier guarantees that other threads will see the value recently given to the field, but it cannot be atomically incremented.
In summary, a local variable declaration cannot be used as a repeating statement in a for, while, or do loop, and it can only appear in a block of statements as a single statement. In addition, when you use a variable to count the creation of an instance, use a long type instead of a variable of type int to prevent overflow. Finally, if you plan to create instances in multiple threads, either synchronize access to the instance counters or use a counter of type Atomiclong.

Java FAQ 55--Special creation theory

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.