tags:

views:

1644

answers:

25

Similar to this question...

What are the worst practices you actually found in Java code?

Mine are:

  • using instance variables in servlets (it's not just bad practice but bug, actually)
  • using Collection implementations like HashMap, and not using the appropriate interfaces
  • using seemingly cryptic class names like SmsMaker (SmsFactory) or CommEnvironment (CommunicationContext)
+4  A: 

Overkill abstraction of object oriented design.

Same answer on a similar thread (applies to all languages which permit object oriented design).

JTA
+16  A: 

Not related strictly to Java, but calling an expensive function over and over instead of storing the result, when you know it won't change. Example:

if (expensiveFunction() > aVar)
    aVar = expensiveFunction();
for (int i=0; i < expensiveFunction(); ++i)
    System.out.println(expensiveFunction());
Claudiu
It depends what you mean by "expensive". Martin Fowler, in his book on re-factoring, actually recommends writing code like this as it is easier to refactor.
oxbow_lakes
how is it easier then using variable with value that was returned by that function? i.e. one line vs X lines...
dusoft
You have to be totally sure that the result of the method is not changing. If the method changes and therefor the result changes more often then thought while writing the depending method your code breaks without you knowing why. If you want to cache do it in the called expensive method. There you know if the result is changing.
Janusz
+1  A: 

Similar to yours, but taken a step further:

Use of class (static) variables when a request scoped variable was the correct thing to do in a Struts action. :O

This was actually deployed in production for a few months, and no one ever noticed a thing until I was reviewing the code one day.

Jack Leow
We had a problem like that lead to a situation where only one user could press the 'Submit' button at a time without getting a stack trace. Luckily the users were internal and eventually somebody on the dev team asked the professional services guys why the kept yelling over the cube wall "Fire in the hole!"
David Moles
+17  A: 
John Topley
I guess you like static imports in Java 6?
Thorbjørn Ravn Andersen
Static imports were introduced in Java 5 and I don't see what they have to do with this point.
John Topley
Allows you to import e.g. Math.cos and refer to it just as cos. See http://java.sun.com/j2se/1.5.0/docs/guide/language/static-import.html
Thorbjørn Ravn Andersen
Math.cos is not a constant. Math.PI would be a better example.
finnw
Math is a concrete class not an interface, so Math.PI is not an example of this anti-pattern.
John Topley
What static imports have to do with this point is that they allow you the convenience of just saying `if (BAD_IDEA)` rather than `if (ConstantsClassPattern.BAD_IDEA)`, without having to extend `InterfaceAntiPattern`.
David Moles
This is the constant interface antipattern, and is one of the reasons why enums were added to Java - http://en.wikipedia.org/wiki/Constant_interface
Jesper
What is the alternative you propose? 1) Using classes is worse because you need to write `public static final` for each constant (which is unnecessary inside an interface). 2) For constants that need to have specific arbitrary values (say, `int MY_INT_CONSTANT = 5423;`) Java 5 enums could be used, but also require more coding.So, IMO, using an interface is often the best choice.
Rogerio
@Rogerio I would recommend that you read Item 19 in Effective Java. "If the constants are strongly tied to an existing class or interface, you should add them to that class or interface. If the constants are best viewed as members of an enumerated type, you should export them with an enum type. Otherwise, you should export the constants with a noninstantiable utility class. In summary, **interfaces should be used only to define types. They should not be used to export constants**."
John Topley
@John Yes, I am familiar with Item 19: "Use interfaces only to define types". It's one of very few items in that excellent book I disagree with. This comes mostly from past experience, in a project where we had hundreds of interfaces just for constants; almost all of those interfaces were nested inside domain entity classes (and some entities had several such interfaces); adding the constants directly would be terrible, because we would lose the interface name, which was a description for an specific grouping of constants. I agree it's not ideal, but the alternatives (enums/classes) are worse.
Rogerio
The argumentation in item 19 of Effective Java (pages 98-99) is actually against classes that *implement* a constant interface in order to use its constants. This is not the way I use them. So, in my case there was never a "leak into the class's exported API", simply because I never had other classes implementing a constant interface. In this respect, I fully agree with item 19.
Rogerio
@Rogerio I understand where you're coming from. Interesting edge case.
John Topley
+7  A: 

Subclassing when you're not supposed to, e.g. instead of using composition, aggregation, etc.

Edit: This is a special case of the hammer.

volley
+6  A: 

Abstracting functionality out into a library class which will never be re-used as it's so specific to the original problem being solved. Hence ending up with a gazillion library classes which no-one will ever use and which completely obscure the two useful utilities you actually do have (i.e. CollectionUtils and IOUtils).

...pauses for breath...

oxbow_lakes
+53  A: 

I had to maintain java code, where most of the Exception handling was like:

catch( Exception e ) {}
asalamon74
People who "throw away" exceptions should be punished!
TM
People also do:catch(Exception e){// will not happen}:)
jb
Unfortunately, my current project has done worse: `catch(Throwable th) { logger.log("something went wrong"); }`
Alan
Hey that's pretty common in C# code as well.
Daud
I admit, while using Oracle's JDBC stuff, that I've written catch (SQLException ex) { /* What could possible be thrown here? */ } when closing a connection.
R. Bemrose
Had one of those. Worked well until there was 1200 concurernt users, then things started to break. Urgh.
Thorbjørn Ravn Andersen
Sometimes I do just want to ignore an exception. But that is _really_ rare.
Isaac Waller
Java quite often requires you to catch an exception that can never happen. For example, an IOException reading from a ByteArrayInputStream - assuming you are in control of the creation of said ByteArrayInputStream.
slim
This is going to open up the whole "checked vs unchecked exceptions" debate! :)
dogbane
or even worse - `catch (Throwable t) {}`
Chii
Catching exception silently and not doing anything about it is the worst sin there is. At some point I found one from Java platform. After intensive debugging of course. I can tell you I was not happy about it.
Carlos
+5  A: 

Our intern used static modifier to store currently logged user in Seam application.

 class Identity{
    ...
    public static User user; 
    ...
 }

 class foo{

    void bar(){
       someEntity.setCreator(Identity.user); 
    }

 }

Of course it worked when he tested it :)

jb
Interns are there to learn, so I guess it is forgivable. Hopefully he won't do it again!
TM
I have done this! My only saving grace is that I was a student, and while the people grading my work didn't catch my mistake, I did figure it out on my next project.
Athena
+11  A: 

The worst Java practice that encompasses almost all others: Global mutable state.

Apocalisp
+9  A: 

Ridiculous OO mania with class hierachies 10+ levels deep.

This is where names like DefaultConcreteMutableAbstractWhizzBangImpl come from. Just try debugging that kind of code - you'll be whizzing up and down the class tree for hours.

madlep
+2  A: 

@madlep Exactly! Parts of the Java community really goes overboard with extreme abstractions and crazily deep class hierarchies. Steve Yegge had a good blog post about it a couple of years back: Execution in the Kingdom of Nouns.

albertb
+6  A: 
if{
 if{
  if{
   if{
    if{
     if{
      if{
       if{
         ....
Steve B.
}}} else { ...
Carlos Heuberger
On a related note, using ifs instead of if-elses: if (i==1) {}if (i==2) {}instead ofif (i==1) {}else if (i==2) {}
dogbane
+3  A: 

I once had to investigate a web application where ALL state was kept in the web page sent to the client, and no state in the web server.

Scales well though :)

Thorbjørn Ravn Andersen
AAAAARRRRRGGGGG
Isaac Waller
For bonus points, also send *user credentials* to the browser.
finnw
Hey, it's RESTful!
David Moles
+9  A: 

Six really bad examples;

  • instead of error reporting, just System.exit without warning. e.g. if(properties.size()>10000) System.exit(0); buried deep in a library.
  • using string constants as locks. e.g. synchronized("one") { }
  • locking on a mutable field. e.g. synchronized(object) { object = ...; }
  • initializing static fields in the constructor.
  • Triggering an exception just to get a stack trace. e.g. try { Integer i = null; i.intValue(); } catch(NullPointerException e) { e.printStackTrace(); }
  • Pointless object creation e.g. new Integer(text).intValue() or worse new Integer(0).getClass()
Peter Lawrey
Oh my brain....
280Z28
+1 for comedy value even though I've been lucky enough never to see any of these in production code
finnw
I still don't know what is wrong with having 10000 properties. ;)
Peter Lawrey
Oh wow, string constants as locks is kind of neat... :)
Lamah
+2  A: 

My favorite sorting algorithm, courtesy of the gray beard brigade:

List needsToBeSorted = new List ();
...blah blah blah...

Set sorted = new TreeSet ();
for (int i = 0; i < needsToBeSorted; i++)
  sorted.add (needsToBeSorted.get (i));

needsToBeSorted.clear ();
for (Iterator i = sorted.iterator (); i.hasNext ();)
  needsToBeSorted.add (i.next ());

Admittedly it worked but eventually I prevailed upon him that perhaps Collections.sort would be a lot easier.

+10  A: 

Once I encountered 'singleton' exception:

class Singletons {
    public static final MyException myException = new MyException();
}

class Test {
    public void doSomething() throws MyException {
        throw Singletons.myException;
    }
}

Same instance of exception was thrown each time ... with exact same stacktrace, which had nothing to do with real code flow :-(

Peter Štibraný
This came up for consideration recently in a discussion I was part of. (And I grimaced.) :o
280Z28
+2  A: 

An API that requires the caller to do:

Foobar f = new Foobar(foobar_id);
f = f.retrieve();

Any of the following would have been better:

Foobar f = Foobar.retrieve(foobar_id);

or

Foobar f = new Foobar(foobar_id); // implicit retrieve

or

Foobar f = new Foobar();
f.retrieve(foobar_id); // but not f = ...
slim
+2  A: 

Not closing database connections, file handles etc in a finally{}

dogbane
+4  A: 

Creating acessors and mutators for all private variables, without stopping to think, sometimes automatically.

Encapsulation was invented for a reason.

Emilio M Bumachar
A: 

A mistake made by junior programmers: unnecessarily using member variables instead of local variables.

A Java EE example:

Starting threads in servlets or EJBs (for example to start asynchronous processing tasks).

This breaks the scalability of your Java EE app. You're not supposed to mess with threading in Java EE components, because the app server is supposed to manage that for you.

We refactored this by having the servlet put a message on a JMS queue and writing a message-driven bean to handle the asynchronous processing task.

Jesper
A: 

Excesive focuse on re-using objects that leads to static things everywhere. (Said re-using can be very helpfull in some situation).

Java has GC build-in, if you need an object, create a new one.

PeterMmm
+1  A: 

Defining the logic using exceptions where a for-loop or any form of loop would suffice.

Example:

while(i < MAX_VALUE)
{
   try
   {
      while(true)
      {
         array[j] = //some operation on the array;
         j++;  

      }
   }
   catch(Exception e)
   {
      j = 0;
   }
}

Serious, I know the guy who wrote this code. I reviewed it and corrected the code :)

Ram
A: 

I saw this line a couple of minutes ago:

Short result = new Short(new Integer(new Double(d).intValue()).shortValue());
cringe
A: 

I think this one for me must be a record. A class is used for building a complex data model for the front end involving filtering. so the method that returns the list of objects goes something like this:

    public DataObjectList (GenerateList (massive signature involving 14 parameters, three of which are collections and one is a collection of collections) 
try { 

250 lines of code to retrieve the data which calls a stored proc that parses some of it and basically contains GUI logic

 } catch (Exception e) {
            return new DataObjectList(e, filterFields);
        }

So I got here because I was wondering how come the following calling method was failing and I couldn't see where the Exception field was being set.

DataObjectList dataObjectList= EntireSystemObject.getDataObjectList Generator().generateDataObjectList (viewAsUserCode, processedDataRowHandler, folderQuery, pageNumber, listCount, sortColumns, sortDirections, groupField, filters, firstRun, false, false, resetView);

dataObjectList.setData(processedDataRowHandler.getData());

if (dataObjectList.getErrorException() == null) {

do stuff for GUI, I think, put lots of things into maps ... 250 lines or so

       }
            return dataObjectList;
        } else {

put a blank version into the GUI and then  

            throw new DWRErrorException("List failed due to list generation error", "list failed due to list generation error for folder: " + folderID + ", column: " + columnID, List.getErrorException(), ListInfo);
        }

All with me so far?

Well at least they did tell us in the front end that something did actually go wrong!

barrymac
A: 

AbstractSpringBeanFactoryFactoryFacadeMutatorBeanFactory. I can't stand this over-engineered, incomprehensible BS. Joel put it a bit more elegantly.

Yevgeniy Brikman