Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.java.programmer > #11881 > unrolled thread

Question about Effective Java

Started byNovice <novice@example..com>
First post2012-02-09 17:54 +0000
Last post2012-02-10 11:59 -0500
Articles 9 — 6 participants

Back to article view | Back to comp.lang.java.programmer


Contents

  Question about Effective Java Novice <novice@example..com> - 2012-02-09 17:54 +0000
    Re: Question about Effective Java markspace <-@.> - 2012-02-09 10:39 -0800
      Re: Question about Effective Java Novice <novice@example..com> - 2012-02-10 00:07 +0000
        Re: Question about Effective Java markspace <-@.> - 2012-02-09 16:42 -0800
    Re: Question about Effective Java Patricia Shanahan <pats@acm.org> - 2012-02-09 14:19 -0800
      Re: Question about Effective Java Novice <novice@example..com> - 2012-02-10 00:40 +0000
        Re: Question about Effective Java Eric Sosman <esosman@ieee-dot-org.invalid> - 2012-02-09 21:08 -0500
          Re: Question about Effective Java Lew <lewbloch@gmail.com> - 2012-02-10 09:01 -0800
    Re: Question about Effective Java "John B. Matthews" <nospam@nospam.invalid> - 2012-02-10 11:59 -0500

#11881 — Question about Effective Java

FromNovice <novice@example..com>
Date2012-02-09 17:54 +0000
SubjectQuestion about Effective Java
Message-ID<Xns9FF4833D32E5Ajpnasty@94.75.214.39>
I'm trying to understand the example on page 14 of Effective Java by Joshua 
Bloch (Second Edition). I hope someone here can help.

Here's the code from the book for the sake of those who don't have the book 
(or the same edition of the book):
=======================================================================
//Builder Pattern
public class NutritionFacts {
	private final int servingSize;
	private final int servings;
	private final int calories;
	private final int fat;
	private final int sodium;
	private final int carbohydrate;
	
	public static class Builder {
		//Required parameters
		private final int servingSize;
		private final int servings;
		
		//Option parameters - initialized to default values
		private int calories = 0;
		private int fat = 0;
		private int carbohydrate = 0;
		private int sodium = 0;
		
		public Builder(int servingSize, int servings) {
			this.servingSize = servingSize;
			this.servings = servings;
		}
		
		public Builder calories(int val) {
			this.calories = val;
			return this;
		}
		
		public Builder fat(int val) {
			this.fat = val;
			return this;
		}
		
		public Builder carbohydrate(int val) {
			this.carbohydrate = val;
			return this;
		}
		
		public Builder sodium(int val) {
			this.sodium = val;
			return this;
		}
		
		public NutritionFacts build() {
			return new NutritionFacts(this);
		}
	}
	private NutritionFacts(Builder builder) {
		this.servingSize = builder.servingSize;
		this.servings = builder.servings;
		this.calories = builder.calories;
		this.fat = builder.fat;
		this.sodium = builder.sodium;
		this.carbohydrate = builder.carbohydrate;
		
	}

}=======================================================================

I should start by saying I have successfully imitated the example in my own 
code. I'm just not entirely sure what it is doing. 

Bloch clearly intends this technique as a way to avoid the confusion of 
methods where you simply have a long list of parameters and could easily 
enter parameters out of order. The code on page 15 shows how much clearer 
things are when you use his technique; all of the optional parameters can 
have clear names so that you know what each one is. I really like this; I 
think it's MUCH better than simply listing a bunch of different integers 
and hoping you assign each one to the right variable. In a nutshell, I get 
what he is doing but I'm just not sure how this code works. 

Questions:
1. I understand that a NutritionFacts could conceivably be just a 
servingSize and a number of servings. All of the other values are optional 
on an individual basis: any one or more of them could be there but don't 
need to be. Any value that is omitted takes a default (of zero in this 
example). But why are the methods calories(), fat(), carbohydrate() and 
sodium() each returning Builder? They aren't constructors and they only 
deal with one data value, fat or calories or whatever, but they apparently 
return a complete Builder.

I'm also having trouble understanding some of the compiler warnings given 
to me by Eclipse (3.7.1) when I actually code the class the way he has it:
- I get a "not used" warning for all of the private final variables in 
NutritionClass (Eclipse offers to delete the variables OR create gettsrs 
and setters OR "add @SuppressWarnings - unused" for each of them. I'm not 
fond of any of these options but what is the best thing to do and why? Why 
does Eclipse think they are unused when the NutritionFacts constructor is 
clearly assigning values to them?
- I get "access to enclosing constructor NutritionFacts
(NutritionFacts.Builder) is emulated by a synthetic accessor method" in the 
return statement of the build() method (Eclipse offers to remove the 
"private" from the constructor for NutritionFacts OR to add 
"@SuppressWarnings - synthetic access" to NutritionFacts but I'm not sure 
which is better and why. 
- I get "read access to enclosing field NutritionFacts.Builder.servingSize 
is emulated by a synthetic accessor method" (Eclipse offers to remove the 
"private" from the variables in Builder OR to add "@SuppressWarnings - 
synthetic access" to NutritionFacts but I'm not sure which is better and 
why. 

-- 
Novice

[toc] | [next] | [standalone]


#11883

Frommarkspace <-@.>
Date2012-02-09 10:39 -0800
Message-ID<jh13se$dve$1@dont-email.me>
In reply to#11881
On 2/9/2012 9:54 AM, Novice wrote:
> I'm trying to understand the example on page 14 of Effective Java by Joshua

> Questions:
> 1. I understand that a NutritionFacts could conceivably be just a
> servingSize and a number of servings. All of the other values are optional
> on an individual basis: any one or more of them could be there but don't
> need to be. Any value that is omitted takes a default (of zero in this
> example). But why are the methods calories(), fat(), carbohydrate() and
> sodium() each returning Builder?


So you can chain calls, like the example at the top of page 15.


> They aren't constructors and they only
> deal with one data value, fat or calories or whatever, but they apparently
> return a complete Builder.


They return a Builder object (which might be the same thing as saying "a 
complete Builder").  Constructors don't have a return type explicitly. 
Learn Java syntax.

public class Builder {
   public Builder() {}         // constructor
   public Builder doIt() {}    // method
}

>
> I'm also having trouble understanding some of the compiler warnings given
> to me by Eclipse (3.7.1) when I actually code the class the way he has it:
> - I get a "not used" warning for all of the private final variables in


Right, it's just a dummy example.  If you add getters to NutritionFacts, 
those warnings will go away.


> NutritionClass (Eclipse offers to delete the variables OR create gettsrs
> and setters OR "add @SuppressWarnings - unused" for each of them. I'm not
> fond of any of these options but what is the best thing to do and why? Why
> does Eclipse think they are unused when the NutritionFacts constructor is
> clearly assigning values to them?


It's a Java thing.  Unused means can't be read, not is not initialized. 
  Things that are initialized and then never used merit a warning message.

[toc] | [prev] | [next] | [standalone]


#11894

FromNovice <novice@example..com>
Date2012-02-10 00:07 +0000
Message-ID<Xns9FF4C2ADB8478jpnasty@94.75.214.39>
In reply to#11883
markspace <-@.> wrote in news:jh13se$dve$1@dont-email.me:

> On 2/9/2012 9:54 AM, Novice wrote:
>> I'm trying to understand the example on page 14 of Effective Java by
>> Joshua 
> 
>> Questions:
>> 1. I understand that a NutritionFacts could conceivably be just a
>> servingSize and a number of servings. All of the other values are
>> optional on an individual basis: any one or more of them could be
>> there but don't need to be. Any value that is omitted takes a default
>> (of zero in this example). But why are the methods calories(), fat(),
>> carbohydrate() and sodium() each returning Builder?
> 
> 
> So you can chain calls, like the example at the top of page 15.
>
I understand that chaining is what we'd like to be able to do. I'm just 
not clear on why "this", which from the method signature is apparently a 
Builder, is being returned by those methods. It _looks_ like each of them 
is returning an entire Builder even though each only contributed one 
"fact" to the Builder.  
> 
>> They aren't constructors and they only
>> deal with one data value, fat or calories or whatever, but they
>> apparently return a complete Builder.
> 
> 
> They return a Builder object (which might be the same thing as saying
> "a complete Builder").  Constructors don't have a return type
> explicitly. Learn Java syntax.
> 
> public class Builder {
>    public Builder() {}         // constructor
>    public Builder doIt() {}    // method
> }
> 
Right; I understand that already. The phrasing of my question is probably 
weird because I can't quite understand what is happening in the example.

>>
>> I'm also having trouble understanding some of the compiler warnings
>> given to me by Eclipse (3.7.1) when I actually code the class the way
>> he has it: - I get a "not used" warning for all of the private final
>> variables in 
> 
> 
> Right, it's just a dummy example.  If you add getters to
> NutritionFacts, those warnings will go away.
> 
But the body of the NutritionFacts constructor is already setting values 
for the variables. I proved that to myself by changing the name of one of 
the NutritionFacts final variables and causing a compiler error in the 
NutritionFacts constructor. Why would getters be needed if the 
constructor is already setting values for the variables? 

> 
>> NutritionClass (Eclipse offers to delete the variables OR create
>> gettsrs and setters OR "add @SuppressWarnings - unused" for each of
>> them. I'm not fond of any of these options but what is the best thing
>> to do and why? Why does Eclipse think they are unused when the
>> NutritionFacts constructor is clearly assigning values to them?
> 
> 
> It's a Java thing.  Unused means can't be read, not is not
> initialized. 

>   Things that are initialized and then never used merit a warning
>   message. 
> 
So if I only initialize it and never read it after that, I can still get 
an "unused" message? If that is right, it explains why the NutritionFacts 
constructor code doesn't prevent the message.

I could have sworn that I've made that warning go away in the past by 
simply doing an assignment statement to give the variable a value, even 
if I never touched it again later. Maybe I'm misremembering that....  


-- 
Novice

[toc] | [prev] | [next] | [standalone]


#11897

Frommarkspace <-@.>
Date2012-02-09 16:42 -0800
Message-ID<jh1p6k$f4s$1@dont-email.me>
In reply to#11894
On 2/9/2012 4:07 PM, Novice wrote:
> I understand that chaining is what we'd like to be able to do. I'm just
> not clear on why "this", which from the method signature is apparently a
> Builder, is being returned by those methods. It _looks_ like each of them
> is returning an entire Builder even though each only contributed one
> "fact" to the Builder.


Patricia had an insight that I missed, which was that only a reference, 
a pointer to the object, gets returned, and indeed that's all Java uses 
is pointers, not "complete objects".

So there's only one Builder, which sits on the heap, and the return 
statement keeps passing a reference to that object back to the code.  I 
usually don't make a distinction because the practical difference is 
small.  But it's there, and can sometimes be helpful when you analyze code.

Also, "this" doesn't mean of the class Builder.  It could be a subclass; 
but inheritance means that you can't tell, and usually shouldn't care.


> So if I only initialize it and never read it after that, I can still get
> an "unused" message? If that is right, it explains why the NutritionFacts
> constructor code doesn't prevent the message.


Yup, unused and can't be used, because they're private.  If you also 
made them public, then some other class might use them, even if none 
actually do.  That would also make the warning go away.

[toc] | [prev] | [next] | [standalone]


#11885

FromPatricia Shanahan <pats@acm.org>
Date2012-02-09 14:19 -0800
Message-ID<QrudnRBcJtTn26nSnZ2dnUVZ_qSdnZ2d@earthlink.com>
In reply to#11881
On 2/9/2012 9:54 AM, Novice wrote:
> I'm trying to understand the example on page 14 of Effective Java by Joshua
> Bloch (Second Edition). I hope someone here can help.
...		
> 		public Builder sodium(int val) {
> 			this.sodium = val;
> 			return this;
> 		}
...:
> 1. I understand that a NutritionFacts could conceivably be just a
> servingSize and a number of servings. All of the other values are optional
> on an individual basis: any one or more of them could be there but don't
> need to be. Any value that is omitted takes a default (of zero in this
> example). But why are the methods calories(), fat(), carbohydrate() and
> sodium() each returning Builder? They aren't constructors and they only
> deal with one data value, fat or calories or whatever, but they apparently
> return a complete Builder.
>

Don't think in terms of "return a complete Builder". Java programs do
not, and cannot, pass objects around as method arguments or results.
sodium really returns a Builder reference. A reference can either be
null or be a pointer to an object of appropriate class.

Inside sodium, "this" is a pointer to the current object. Returning it
allows chaining of several method calls.

Patricia

[toc] | [prev] | [next] | [standalone]


#11896

FromNovice <novice@example..com>
Date2012-02-10 00:40 +0000
Message-ID<Xns9FF4C853AB5ACjpnasty@94.75.214.39>
In reply to#11885
Patricia Shanahan <pats@acm.org> wrote in
news:QrudnRBcJtTn26nSnZ2dnUVZ_qSdnZ2d@earthlink.com: 

> On 2/9/2012 9:54 AM, Novice wrote:
>> I'm trying to understand the example on page 14 of Effective Java by
>> Joshua Bloch (Second Edition). I hope someone here can help.
> ...          
>>           public Builder sodium(int val) {
>>                this.sodium = val;
>>                return this;
>>           }
> ...:
>> 1. I understand that a NutritionFacts could conceivably be just a
>> servingSize and a number of servings. All of the other values are
>> optional on an individual basis: any one or more of them could be
>> there but don't need to be. Any value that is omitted takes a default
>> (of zero in this example). But why are the methods calories(), fat(),
>> carbohydrate() and sodium() each returning Builder? They aren't
>> constructors and they only deal with one data value, fat or calories
>> or whatever, but they apparently return a complete Builder.
>>
> 
> Don't think in terms of "return a complete Builder". Java programs do
> not, and cannot, pass objects around as method arguments or results.
> sodium really returns a Builder reference. A reference can either be
> null or be a pointer to an object of appropriate class.
> 
> Inside sodium, "this" is a pointer to the current object. Returning it
> allows chaining of several method calls.
>
I'll have to mull that over for a bit and consider the implications. 

At first glance it seems simple enough; in any other class, "this" refers 
to an instance of the class that contains the "this", just like we see 
here. But I'm not used to seeing several methods in a class all return 
"this". I'm also not used to named classes nested within classes. (I'm 
familiar with anonymous inner classes like window listeners and with 
putting additional named classes within the same source file in a 
sequential fashion but putting a named class within another is still 
feels a little odd.)

I'll post back if I can't make my peace with this slightly exotic 
technique ;-)

Thanks for your help.
 
-- 
Novice

[toc] | [prev] | [next] | [standalone]


#11899

FromEric Sosman <esosman@ieee-dot-org.invalid>
Date2012-02-09 21:08 -0500
Message-ID<jh1u7n$691$1@dont-email.me>
In reply to#11896
On 2/9/2012 7:40 PM, Novice wrote:
> Patricia Shanahan<pats@acm.org>  wrote in
> news:QrudnRBcJtTn26nSnZ2dnUVZ_qSdnZ2d@earthlink.com:
>
>> On 2/9/2012 9:54 AM, Novice wrote:
>>> I'm trying to understand the example on page 14 of Effective Java by
>>> Joshua Bloch (Second Edition). I hope someone here can help.
>> ...
>>>            public Builder sodium(int val) {
>>>                 this.sodium = val;
>>>                 return this;
>>>            }
>> ...:
>>> 1. I understand that a NutritionFacts could conceivably be just a
>>> servingSize and a number of servings. All of the other values are
>>> optional on an individual basis: any one or more of them could be
>>> there but don't need to be. Any value that is omitted takes a default
>>> (of zero in this example). But why are the methods calories(), fat(),
>>> carbohydrate() and sodium() each returning Builder? They aren't
>>> constructors and they only deal with one data value, fat or calories
>>> or whatever, but they apparently return a complete Builder.
>>>
>>
>> Don't think in terms of "return a complete Builder". Java programs do
>> not, and cannot, pass objects around as method arguments or results.
>> sodium really returns a Builder reference. A reference can either be
>> null or be a pointer to an object of appropriate class.
>>
>> Inside sodium, "this" is a pointer to the current object. Returning it
>> allows chaining of several method calls.
>>
> I'll have to mull that over for a bit and consider the implications.
>
> At first glance it seems simple enough; in any other class, "this" refers
> to an instance of the class that contains the "this", just like we see
> here. But I'm not used to seeing several methods in a class all return
> "this".

     Analogies are never perfect, but often helpful.  So, imagine a
group of friends ordering pizza: They've got a slip of paper listing
possible toppings, and they're going to put check marks next to the
items they want.  "Pepperoni," says George, "gotta have pepperoni,"
making his mark on the paper and passing it to Gina.  "Mushrooms
make my breath fresher," she says, adding her mark and passing the
paper along to Gail.  She opts for extra cheese and hands the paper
to Guy, who's worried about his weight and says "Sounds good, let's
just go with these three."  He passes the paper over the counter to
Guido, who makes them a pluperfectly personalized pizza.

     Now, what do the friends pass among themselves during this
colloquy?  Do they pass the pizza?  No, it hasn't even been made
yet.  Do they pass their chosen ingredients?  No, George doesn't
have a handful of pepperoni, nor does Gina have mushrooms nor Gail
extra cheese, and Guy doesn't have plenty of nothing.  What they
pass is the slip of paper, the specification of the pizza they would
like Guido to build for them.

     ... and that's very much like what's going on with Builder and
NutritionFacts.  The friends "make marks on" a Builder, then hand
the Builder to Guido, who makes them a NutritionFacts built to its
specification.

     That's the idea; now to the returning of "this".  It's just a
convenience, really.  Imagine that all those Builder methods were
"void", returning nothing at all.  Then you'd write

	NutritionFacts.Builder b = new NutritionFacts.Builder(300, 4);
	b.calories(950);
	b.sodium(800);
	b.carbohydrate(1025);
	NutritionFacts facts = b.build();

That is, you'd use the variable "b" to hold a reference to the
Builder while you "make your marks" on it.  Eventually, you call
its build() method to "hand it to Guido" and get a pizza -- er,
that is, a NutritionFacts -- made to order.  This would work just
fine, and there's nothing fundamentally wrong with it.

     But if each of the Builder method returns a reference to the
Builder it has just "marked" things can be written a little more
compactly:

	NutritionFacts facts =
	    new NutritionFacts.Builder(300, 4)
	       .calories(950)
	       .sodium(800)
	       .carbohydrate(1025)
	    .build();

Observe that you no longer need the "b" variable: The "new" creates
a Builder and produces a reference to it, the calories() method
modifies that Builder and returns a reference that the sodium()
method can use, ..., until eventually the build() method takes all
the information stored in the Builder and uses it to generate a
Pizza -- er, that is, a NutritionFacts.  Since there's no "b" to
refer to the Builder, it becomes eligible for garbage collection
as soon as its fulfilled its purpose, namely, specifying what's
wanted in the new NutritionFacts.

     In short, the returning of "this" enables a convenience, but
is not truly fundamental to the pattern of using a builder of some
kind to hold the parameters for a hidden constructor.

> I'm also not used to named classes nested within classes. (I'm
> familiar with anonymous inner classes like window listeners and with
> putting additional named classes within the same source file in a
> sequential fashion but putting a named class within another is still
> feels a little odd.)

     You'll get used to it.  The pattern works even if the builder
class is completely separate from the built class -- consider, for
example, StringBuilder and String.  (And note how StringBuilder's
append() method, for instance, returns a reference to the same
StringBuilder that the append() modified.)

> I'll post back if I can't make my peace with this slightly exotic
> technique ;-)

     You'll get used to it.  (Is there an echo in here?)

-- 
Eric Sosman
esosman@ieee-dot-org.invalid

[toc] | [prev] | [next] | [standalone]


#11908

FromLew <lewbloch@gmail.com>
Date2012-02-10 09:01 -0800
Message-ID<31230663.214.1328893287858.JavaMail.geo-discussion-forums@pbcpo5>
In reply to#11899
On Thursday, February 9, 2012 6:08:51 PM UTC-8, Eric Sosman wrote:
> On 2/9/2012 7:40 PM, Novice wrote:
> > At first glance it seems simple enough; in any other class, "this" refers
> > to an instance of the class that contains the "this", just like we see
> > here. But I'm not used to seeing several methods in a class all return
> > "this".

Get used to it.

Have you considered Googling for "builder pattern"? You might be surprised by 
what just a few minutes of reading can reveal.

>      Analogies are never perfect, but often helpful.  So, imagine a
> group of friends ordering pizza: They've got a slip of paper listing
> possible toppings, and they're going to put check marks next to the
> items they want.  "Pepperoni," says George, "gotta have pepperoni,"
> making his mark on the paper and passing it to Gina.  "Mushrooms
> make my breath fresher," she says, adding her mark and passing the
> paper along to Gail.  She opts for extra cheese and hands the paper
> to Guy, who's worried about his weight and says "Sounds good, let's
> just go with these three."  He passes the paper over the counter to
> Guido, who makes them a pluperfectly personalized pizza.
> 
>      Now, what do the friends pass among themselves during this
> colloquy?  Do they pass the pizza?  No, it hasn't even been made
> yet.  Do they pass their chosen ingredients?  No, George doesn't
> have a handful of pepperoni, nor does Gina have mushrooms nor Gail
> extra cheese, and Guy doesn't have plenty of nothing.  What they
> pass is the slip of paper, the specification of the pizza they would
> like Guido to build for them.
> 
>      ... and that's very much like what's going on with Builder and
> NutritionFacts.  The friends "make marks on" a Builder, then hand
> the Builder to Guido, who makes them a NutritionFacts built to its
> specification.
> 
>      That's the idea; now to the returning of "this".  It's just a
> convenience, really.  Imagine that all those Builder methods were
> "void", returning nothing at all.  Then you'd write
> 
> 	NutritionFacts.Builder b = new NutritionFacts.Builder(300, 4);
> 	b.calories(950);
> 	b.sodium(800);
> 	b.carbohydrate(1025);
> 	NutritionFacts facts = b.build();
> 
> That is, you'd use the variable "b" to hold a reference to the
> Builder while you "make your marks" on it.  Eventually, you call
> its build() method to "hand it to Guido" and get a pizza -- er,
> that is, a NutritionFacts -- made to order.  This would work just
> fine, and there's nothing fundamentally wrong with it.
> 
>      But if each of the Builder method returns a reference to the
> Builder it has just "marked" things can be written a little more
> compactly:
> 
> 	NutritionFacts facts =
> 	    new NutritionFacts.Builder(300, 4)
> 	       .calories(950)
> 	       .sodium(800)
> 	       .carbohydrate(1025)
> 	    .build();
> 
> Observe that you no longer need the "b" variable: The "new" creates
> a Builder and produces a reference to it, the calories() method
> modifies that Builder and returns a reference that the sodium()
> method can use, ..., until eventually the build() method takes all
> the information stored in the Builder and uses it to generate a
> Pizza -- er, that is, a NutritionFacts.  Since there's no "b" to
> refer to the Builder, it becomes eligible for garbage collection
> as soon as its fulfilled its purpose, namely, specifying what's
> wanted in the new NutritionFacts.
> 
>      In short, the returning of "this" enables a convenience, but
> is not truly fundamental to the pattern of using a builder of some
> kind to hold the parameters for a hidden constructor.
> 
> > I'm also not used to named classes nested within classes. (I'm

Read the Java tutorials.

Then study the Java Language Specification (JLS) about "member types".

The keyword is "scope". The scope of a nested class is defined like any other 
class or instance member: 'public', 'protected', package-private or 'private'.
There are also some special rules about access to the enclosing type's members.

> > familiar with anonymous inner classes like window listeners and with

It's the same, but anonymous classes don't have a name (hence "anonymous").

Do note that not all nested classes are inner classes; some are static.

> > putting additional named classes within the same source file in a
> > sequential fashion but putting a named class within another is still
> > feels a little odd.)

"Not familiar", "feels a little odd". Jeez, get over it. You sound like a 
whiney little baby.

If you haven't got the ability to learn new stuff, you won't last 10 minutes in 
software development. Really, get over it.

>      You'll get used to it.  The pattern works even if the builder
> class is completely separate from the built class -- consider, for
> example, StringBuilder and String.  (And note how StringBuilder's
> append() method, for instance, returns a reference to the same
> StringBuilder that the append() modified.)
> 
> > I'll post back if I can't make my peace with this slightly exotic
> > technique ;-)

Why don't you first study up on it? The newsgroup is not a help desk, and it 
certainly is no substitute for study.

And you call it "exotic" only because you're incompletely trained. Don't make
such judgments given your lack of experience. You are in no position yet to 
decide what is "exotic" and what isn't. You need to check your ego at the door.

>      You'll get used to it.  (Is there an echo in here?)

Bottom line: Study, and get used to learning new things.

-- 
Lew

[toc] | [prev] | [next] | [standalone]


#11906

From"John B. Matthews" <nospam@nospam.invalid>
Date2012-02-10 11:59 -0500
Message-ID<nospam-7490FA.11593110022012@news.aioe.org>
In reply to#11881
In article <Xns9FF4833D32E5Ajpnasty@94.75.214.39>,
 Novice <novice@example..com> wrote:

> I'm trying to understand the example on page 14 of Effective Java by Joshua 
> Bloch (Second Edition). I hope someone here can help.
> 
> Here's the code from the book for the sake of those who don't have the book 
> (or the same edition of the book):

Excerpted here: <http://drdobbs.com/jvm/208403883?pgno=2>.

[...]
-- 
John B. Matthews
trashgod at gmail dot com
<http://sites.google.com/site/drjohnbmatthews>

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.java.programmer


csiph-web