Creating String Objects

     

Strings are objects. Their superclass is java.lang.Object (they inherit all of the properties and methods defined in the Object class, and then define some of their own). As we know, everything in Java is an object (except for the primitive types such as int , boolean , and char ), and they all have corresponding object types that are often called "wrappers".

If you want to be a big nerd and make everyone hate you, create a String like you would a regular object:

 

 String s = new String("Sucker!!!"); 

If, for some reason, you do not want to be a big gigantic nerd and force everyone to hate you, use the following simpler, more common, and more efficient syntax to create a String:

 

 String s = "All the cool kids do it"; 

If Java provides us with this different constructor syntax, what is the problem with creating it the longer and more familiar way?

The easy reason is that no one does it, so it is unexpected behavior. And although you are lovely and singular and creativity is your strong suit, the declaration and initialization of your Strings is not the place to make your artistic statement. In other words, predictability is very good. Be predictable. The poor schmoes who inherit our code will be just a little less poor. Let's look at the possibly more important technical reasons in the following sections.

One String for the Price of Two

The following is called a String literal:

 

 "This is da creeda of Jacques Derreeda"; 

It's a bunch of characters between double quotes. The compiler will automatically create a new String object for every literal it stumbles across in your program. Sound weird? Think about what happens when the new keyword is invoked? Java does what it's told and creates a new object on the heap. But what does it do when you use the new keyword and give it a String literal in the same statement?

Consider. You're the virtual machine. You're supposed to create a new object when you see new and you're supposed to create a new object when you see a String literal. So, you create two objects, just as you're told to do.

As you might imagine, specifying only the String literal, instead of using the new keyword, is far more efficient, because only the object literal is created.

That begs the question, "Do I have two Strings then, each with the same value?" The answer, as you might not expect, is, "No, you don't." See the "String References and Immutability" section to find out why.

Converting a Char Array into a String

Despite the performance penalty described previously, sometimes it is necessary to create Strings using the new keyword. And that's just fine. I'm not getting all weird about it. I'm just saying don't do it if you don't have to. It's perfect, for instance, when you have an array of characters, and you need to get that array into a String object. In these cases, you must use the constructor. Here's what to do:

 

 char[] myCharArray = {'g','a','r','a','g','e'}; String myString = new String(myCharArray); System.out.println(myString); 

Note that you cannot convert directly to a String. That is, you cannot do this:

 

 String myString = myCharArray; //won't compile 

(See the "Strings and Security" section to find out why.)

Note that the String class contains a couple of different ways to do this; the other way also takes an int letting you specify the offset.

Converting a ByteArray into a String

There is also a String constructor that accepts a byte array. Say you use the New IO library introduced in Java 1.4 to read in the contents of a file to a ByteBuffer, like this:

 

 Row row = null;    rows = Collections.synchronizedList (new ArrayList(numberOfRecords));    for (int i = 0; i < numberOfRecords; i++){       row = new Row(metaData);       Charset charset = Charset.forName("US-ASCII")       CharsetDecoder decoder = charset.newDecoder();       byte isDeleted = bb.get();       row.setIsDeleted(isDeleted);       ByteBuffer bIn =              ByteBuffer.allocate(LENGTH_OF_LINE);       CharBuffer cb =              CharBuffer.allocate(LENGTH_OF_LINE);       cb.rewind();       charset.newDecoder().decode(bb,cb,false);       cb.rewind();       String s = cb.toString();       synchronized(datarows){           //put record into list that the app will use                 rows.add(convert(row, s));         }     } 

There is obviously code here that we haven't discussed yet. I'm just providing you with a code snippet that will read in an ASCII file, which only requires seven bits to render a character (not 16 like Unicode) into an array of bytes so that you can make a String out of it. If I didn't include the code, then it might be hard to see where you would get a byte array in the first place. But the above code example reads each line in the file, calling a separate method called convert as it uses the data to create a Row object.

Once we have that byte array, we can covert each line into a String. Like this:

 

 Column c = new Column(); c.setSomeShortData(bb.getShort()); byte[] arrFieldName = new byte[c.getLenFieldName()]; bb.get(arrFieldName, 0, arrFieldName.length); try {     String data = new String(arrFieldName,"US-ASCI");     c.setData(data); } catch (UnsupportedEncodingException e) {     e.printStackTrace(); } 

If this all seems like too much right now, definitely do not sweat it. Onto the next . But if later you discover you need some byte-array-readin-string-makin' code, there you have it.



Java Garage
Java Garage
ISBN: 0321246233
EAN: 2147483647
Year: 2006
Pages: 228
Authors: Eben Hewitt

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net