pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

(Via [personal profile] pseudomonas.)

perl -le 'print "$_ + 1 = ", $_ + 1 for qw/milli micro nano pico/'

I is a SCJP!

Wednesday, 15 August 2012 14:16
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

I took the Test Formerly Known As Sun Certified Java Programmer (no idea what it’s called these days; Oracle Certified Professional or some such, I think), and passed with flying colours!

I got 96% compared to a passing mark of 61%, so I got two of the 60 questions wrong. (And given the two topics that the score report said I need work on, I’m fairly sure it’s one where I assumed that File.renameTo() took a String argument rather than a File and one where I had forgotten that Thread has a .run() method.)

So now I wait for the proper certificate, but whee! I is a SCJP!

Next step, possibly: SCJD. As in, the test that doesn’t test you on arcane syntax details and API method arguments, but actually makes you develop some software. Kind of like the difference between ivory-tower learning and actually showing you can get your hands dirty and construct something that not only works but was constructed properly. Though a co-worker is shooting for a Java EE Web Component Developer exam next.

Let’s see how the work situation plays out; I’ll probably try to start work on SCJD when it looks as if there’s a lull in between projects, which could be soon or could be a while. (There’s news about a new project, but we’re waiting for confirmation from the project leader, who will be coming back from holiday on the 20th.)

pne: A typographical ligature of the lowercase letters "wtf" (wtf ligature)

OK, this is the third thing this day; I’ma start a new entry which I’ll update occasionally.

Now this one is not so much incorrect, but still, the irony just slays me:

int key []; // brackets after name (legal but less readable)
            // spaces between the name and [] legal, but bad

Spaces before the [] are bad? Like the spaces they use in String [] args in just about every main method in the book?

The mind, it reels.

OK, not a WTF as such, but still:

[…] Instance init blocks are often used as a place to put code that all the constructors in a class should share. That way, the code doesn't have to be duplicated across constructors.

I’d like to dispute the “often” in there, given that I had never heard of instance init blocks before (nor seen then used), ever. (Though the syntax and usage is reasonable based on what I did know about static init blocks.)

I’m also distinctly unimpressed that one of the questions in the self-test in Chapter 2 relies on overloading method resolution information that will be taught in Chapter 3.

More String nonsense

Creating String objects

Oh dear! More nonsense about how String objects work:

In Java, strings are objects. Just like other objects, you can create an instance of a String with the new keyword, as follows:

String s = new String();

This line of code creates a new object of class String, and assigns it to the reference variable s. So far, String objects seem just like other objects. Now, let's give the String a value:

s = "abcdef";

As you might expect, the String class has about a zillion constructors, so you can use a more efficient shortcut:

String s = new String("abcdef");

And just because you'll use strings all the time, you can even say this:

String s = "abcdef";

There are some subtle differences between these options that we'll discuss later, but what they have in common is that they all create a new String object, with a value of "abcdef", and assign it to a reference variable s.

Except that the first pair of statements created two String objects: one for the empty string (which got assigned to the s variable), and then another one containing "abcdef", which then also got assigned to s (leaving the object that s previously referred to, the empty string, not referred to any more (and presumably eligible for garbage collection).

One string object and two string objects seems like a difference to me.

Understanding Strings

…Oh dear, and a bit later, they say:

[…] If you really, really get the examples and diagrams, backward and forward, you should get 80 percent of the String questions on the exam correct.

I think I do; thanks! It just doesn’t seem to me as if the authors did….

Substring index values

[…] If the [substring() method] call has two arguments, the substring returned will end with the character located in the nth position of the original String where n is the second argument. Unfortunately, the ending argument is not zero-based, so if the second argument is 7, the last character in the returned String will be in the original String's 7 position, which is index 6 (ouch). […]

Ouch indeed. Wouldn’t explaining that the indexes run from beginIndex, inclusive, to endIndex, exclusive, have been easier than invoking one-based counting?

Or using wording such as “the substring returned will end with the character immediately before the index given by the second argument”.

Why StringBuilder is better than String, or, When objects get added to the String constant pool


[…] if you choose to do a lot of manipulations with String objects, you will end up with a lot of abandoned String objects in the String pool. (Even in these days of gigabytes of RAM, it's not a good idea to waste precious memory on discarded String pool objects.) On the other hand, objects of type StringBuffer and StringBuilder can be modified over and over again without leaving behind a great effluence of discarded String objects.

Is this really the reason?

As I understand it, every string literal will be added to the String constant pool, but results of methods such as String.concat() will not.


String s = "Hello ";
s += "world, ";
s += "how are ";
s += "you?";

Would end up with four objects in the String constant pool (the four string literals), one String object on the heap (with value Hello world, how are you?) pointed to by s, and two String objects on the heap produced by the += operator (with values Hello world, and Hello world, how are ) which are not pointed to by anything and are eligible for garbage collection.

While if you did

StringBuilder s = new StringBuilder(26);
s.append("Hello ");
s.append("world, ");
s.append("how are ");

Would end up with… tada, four! objects in the String constant pool, as before! Since we still have four String literals in the source.

You’d avoid the two temporary String objects produced by the concatenation in the first example, but those are (if I understand correctly) on the heap and eligible for garbage collection, not “wast[ing] precious memory” as a case of “discarded String pool objects”. Sure, those are “discarded String objects”, but they’re not clogging up the scarce String pool resource and never getting freed. So you’re still polluting your scarce resource just as much as before, just using a bit less of a less-scarce one (the heap).

…and if you had used the new StringBuilder(); constructor instead, you’d have a discarded char[] lying around on the pool from when the StringBuilder had to resize from its default 16 to 34 characters upon appending the “how are ” bit. So on this particular example, you save one heap object with StringBuilder compared to String.

Using StringBuilder and StringBuffer

String x = "abc";
x = x.concat("def");
System.out.println("x = " + x);     // output is "x = abcdef"

We got a nice new String out of the deal, but the downside is that the old String "abc" has been lost in the String pool, thus wasting memory. If we were using a StringBuffer instead of a String, the code would look like this:

StringBuffer sb = new StringBuffer("abc");
System.out.println("sb = " + sb);    // output is "sb = abcdef"

…which would still lose “the old String "abc"” to the String pool, as I understand it, since it would be added to the String pool at the point where the compiler saw the String literal "abc" in the source code: it would create a String object in the constant pool (or find an existing String object with that value in the pool), and then pass that String object to the constructor of StringBuffer. You’re not doing the constant pool any favours here.

Lenient: I don’t think that means what you think it means.

The API for DateFormat.parse() explains that by default, the parse() method is lenient when parsing dates. Our experience is that parse() isn't very lenient about the formatting of Strings it will successfully parse into dates; take care when you use this method!

I wonder whether they’re using the same definition of “lenient” as the API; it doesn’t mean that it can take stuff such as “last Thursday” or “ye 13th of the monthe of Maye of the Year of Our Lord 1492”, but rather that it can take stuff such as “2001-2-31” and turn it into “2001-03-03”. As the API says, it does have to be parsable as a date; but you can omit leading zeroes or talk about the 31st of February.

pne: A typographical ligature of the lowercase letters "wtf" (wtf ligature)

Quoth the SCJP study guide:

Arrays are efficient, but most of the time you'll want to use one of the Collection types from java.util (including HashMap, ArrayList, TreeSet). Collection classes [… a]re really managed arrays, since they use arrays behind the scenes. […]

ORLY. Show me how a TreeSet uses arrays behind the scenes. Or a LinkedList, which—though they didn’t mention it explicitly—is also “one of the Collection types from java.util”.)


If this goes on much further, I’ll have to create a separate entry just for their weirdness rather than posting as I go along.

pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

So I’m preparing for the Sun Certified Java Programmer for Java 6 course (now Oracle Certified Professional or something like that, I think, but the book still calls it SCJP).

And I come across this lovely bit in chapter 3:

One exception to the way object references are assigned is String. In Java, String objects are given special treatment. For one thing, String objects are immutable; you can't change the value of a String object […]. But it sure looks as though you can. Examine the following code:

String x = "Java";  // Assign a value to x
x = x + " Bean";    // Now modify the object using
                    // the x reference


For any other object type, where two references refer to the same object, if either reference is used to modify the object, both references will see the change because there is still only a single object. But any time we make any changes at all to a String, the VM will update the reference variable to refer to a different object. […]

You need to understand what happens when you use a String reference variable to modify a string:

  • A new string is created (or a matching String is found in the String pool), leaving the original String object untouched.
  • The reference used to modify the String (or rather, make a new String by modifying a copy of the original) is then assigned the brand new String object.

So when you say

1. String s = "Fred";
2. String t = s;     // Now t and s refer to the same
                     // String object
3. t.toUpperCase();  // Invoke a Strong method that changes
                     // the String

you haven't changed the original String object created on line 1. When line 2 completes, both t and s reference the same String object. But when line 3 runs, rather than modifying the object referred to by t (which is the one and only String object up to this point), a brand new String object is created. And then abandoned. […]

(Emphasis in the original.)

Which contains a bunch of lies. (Not all of it, but too much of it.)

As best as I can see, String objects aren’t special in this particular respect; the same is true of other immutable classes.

It all boils down to the fact that you can’t modify String objects. If you want to change the value, you get a new String object, whether this is because you applied an operator (s + " Bean") or called a method on it (t.toUpperCase()). Assigning this new object to a variable, uh, assigns this new object to the variable. Same behaviour as when you assign any new object to a reference variable: other variables that reference the object that the variable used to point to continue to refer to the previous object.

It’s exactly the same with, say, java.math.BigDecimal, which is also not mutable and which returns new objects if you try to do arithmetic. For example, in BigDecimal first = new BigDecimal("17"); BigDecimal copy = first; BigDecimal second = new BigDecimal("21"); first = first.add(second);, the “add” method will return a new BigDecimal object. If you turn around and assign it straight back to the variable “first”, then that doesn’t change the BigDecimal object that had the value 17; that one is still around and still pointed to by the variable “copy”; it’s just not pointed to by the variable “first” any more.

So s = s + " Bean"; is not any more special than s = "C#";; in both cases, we point the variable to a new String object. There’s no “mak[ing] any changes […] to a String” or “changes the String” of any kind going on anywhere, nor any “special treatment” of String objects that I can see.


pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

I googled for a Java problem I had, and one of the top hits was Reading there answered my question (and another one I didn’t even know I had!), but it was a bit surreal to find the answer on an LDS site.

@ vs. $#

Monday, 10 May 2010 11:19
pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

I was reading a tutorial on Perl autovivification and came across this bit of code, testing whether a number was a valid array index:

return unless 0 <= $key && $key < @{$ref} ;

And I thought “meh”, because the author used @{$ref} in a comparison for a valid index.

I would have used && $key <= $#{$ref} (well, actually probably $#$ref) instead.

Because, for me, @foo (in scalar context) is the number of entries in @foo, so you’d use it for things like seeing whether you have enough arguments to a subroutine, or whether an array is empty, or that sort of thing: where you’re interested in the number of entries. $#foo, on the other hand, is the last valid index in @foo, so you’d use it when you’re interested in valid indices (indexes?) such as the comparison above or the classic for ($i = 0; $i <= $#foo; $i++) C-style for loop over the indices of an array.

Sure, the two are related to one another (@foo is one more than $#foo, unless you’ve messed with $[, which you probably shouldn’t), but for me, the two are semantically different, and using either expression in something semantically related to the other feels wrong to me.

Of course, YMMV; Perl is (at least supposedly) all about TMTOWTDI and accepting of others’ programming styles. So I’ll just say that that’s how I think of them.

pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

“The relation is based on the key, the whole key, and nothing but the key—so help me Codd.”

Found this in Wikipedia, and I think it’s really amusing!

pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)

Why does the response character encoding in my JSP-based application change after I set it?

In some cases web applications set the response character encoding (which corresponds to the charset value of the content type), but the web page sent to the browser is actually encoded in a different encoding. This problem can occur when using a Servlet 2.3 based container together with the JavaServer Pages Standard Tag Library. The sequence of events is:

  1. Application sets the content type including a charset value. This sets the response character encoding.
  2. Application uses a JSTL tag that accesses a resource bundle.
  3. JSTL sets the response locale to the locale that led to the resource bundle found.
  4. The container sets the response character encoding to an encoding that's suitable for the response locale, but may be different from the previously set character encoding.

This problem was solved in the Servlet 2.4 specification by distinguishing between explicit and implicit character encoding specifications. Setting the character encoding through the content type or via the new method ServletResponse.setCharacterEncoding are explicit specifications, while determining it from a locale setting is an implicit specification. Implicit specifications cannot override explicit specifications, so event 4) above does not occur.

If your application needs to be compatible with containers based on older specifications, you must freeze the character encoding by calling ServletResponse.flushBuffer between the explicit character encoding specification and the first use of custom actions that might implicitly determine the character encoding.


pne: A picture of a plush toy, halfway between a duck and a platypus, with a green body and a yellow bill and feet. (Default)
Philip Newton

June 2015

 12 3456
2122232425 2627


RSS Atom

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Saturday, 21 October 2017 06:38
Powered by Dreamwidth Studios