Friday, November 30, 2007

Assignment does not give a copy.

In my naive assuption, I believed that the statement


myMethod Report(Report report){
Report copyofreport = report;
return copyofreport;
}


would give me a new object, an instance of the class Report.

It kind of worked, but introduced a subtle bug. I tried calling this method multiple times, thinking I could get an array of identical reports- but when I did something to my first report, all of the 'copies' I had made were similarly affected, even though I hadn't touched them.

What this actually did was make an array of references that all pointed to my original object, report. when I changed one, the references all reflected the same change.

solution: to make a new, identical object, there's a handy interface called cloneable. implement cloneable, override the method if necessary, and then call .clone().



// public class Report implements Cloneable;
ReportmyMethod Report(Report report){
Report copyofreport = report.clone();
return copyofreport;
}



Much better.
This only creates a 'shallow copy' though, so if there are any inner objects in the cloneable class, the objects will have the same reference. This really only matters if you're going to change the inner objects, but it's good to be aware of.

Wednesday, November 21, 2007

exceptions?

As a still relatively new Java programmer, I'm still having trouble deciding whether or not to throw Exceptions in parts of my code that can go wrong.
This site is a great reference for what to do and what to avoid.


http://today.java.net/pub/a/today/2006/04/06/exception-handling-antipatterns.html



The most useful part: Antipatterns: what you really *shouldn't* do, and why. Here's an excerpt:


catch (NoSuchMethodException e) {
LOG.error("Blah", e);
throw e;
}


"This is one of the most annoying error-handling antipatterns. Either log the exception, or throw it, but never do both. Logging and throwing results in multiple log messages for a single problem in the code, and makes life hell for the support engineer who is trying to dig through the logs."

So true!!

I gotta get a me whole book of antipatterns....

Tuesday, November 20, 2007

Dude, where's my method?

So I was creating a new method in a class. This method the same name, but different signature of an existing method, but it took in different arguments. I finished writing the method bodies, and went back to the class that called my new method.


Oddly, I got the error:

"The method getExchangeDelayPlot(ReportOptions) in the type ExchangeDelaysDAO is not applicable for the arguments (ReportRequest)".


Me: .".what are you talking about, stupid eclipse. I made the method getExchangeDelayPlot(ReportRequest), and saved it, and got no compiler errors. are you blind or something?"


Of course, my IDE was not blind. (isn't that always the case).

What I missed: Although I had added the method to the concrete class (ExchangeDelaysDAOImpl), I was trying to call the method its parent abstract class above this. I had forgotten to add the empty method signature of the new method to the abstract class.


Lesson 1: look carefully at the *type* in the error message.

Lesson 2: remember class hierarchies: remember to add method signatures to any abstract classes or interfaces you're trying to call your methods from.

Wednesday, November 14, 2007

The trouble with arrays

I've always had trouble with arrays. Either I forget to initialize 'em, or worry about hardcoding the upper limit of values they can take... they're a pain.

names = new String[100]; //why 100? it's a magic number! boo!


So I think it's time to work with dynamic arrays. In Java 5.0 and beyond there is a class called
ArrayList
, which is similar to an array, but has no upper limit (hardcoded, anyways). Plus it's dynamic.

but what if I want to sort my strings? I need them in alphabetical order sometimes.
alphabetical sorts are easy peasy with arrays:

java.util.Arrays.sort(array);

There is no ArrayList.sort() method. Luckily, it's a type of Collection, and Collections do have sort methods.


import java.util.ArrayList;
import java.util.Collections;
...
Collections.sort( myArrayList );

Ta-da!

Tuesday, November 13, 2007

Cannot make a static reference to the non-static method

ComponentMap cm = GenericRDSFactory.getRDSComponents(rr);


(where GenericRDSFactory is a different class): gives the error

"Cannot make a static reference to the non-static method":

The static keyword just means that the method or attribute belongs to that class.

The solution: instantiate the class first, then invoke the methods from the new object.

GenericRDSFactory factory = new GenericRDSFactory();

ComponentMap cm = factory.getRDSComponents(rr);