23
votes

I've gone through a few Java questions on SO. And I must say the content here is pretty well written and the Java guys on SO can really pump out the answers.

But what I always found was Java answers for Java people. Which is great on its own, but I'm a Java noob. So I don't really care for the workings of "Joint union in type parameter variance". It's probably handy down the line but for now.. it's not.

So Java for a noob (coming from PHP and Python) what are the cheatcodes?

If you could link to an SO answer (which is probably out there but I couldn't find) or write up what are the things Java does differently than other languages? (on a basic level)

Some might call these the Java Gotchas (I couldn't find the official one though)

23
Java Anti-patterns (bad code that may not look so obiously bad for java beginners) odi.ch/prog/design/newbies.phpAries McRae
Look here.Daniel Hiller
The "Common Gotchas" question is indeed similar, but this one has a clear emphasis on beginner gotchas...Jonik

23 Answers

16
votes

There's a collection of semi-official "gotchas", known as the Java Puzzlers, and documented in a book of the same name; you might also find a few screencasts on the web. Periodically, Joshua Bloch and Neal Gafter like to present a bunch of innocuous-looking challenges and proceed to systematically remove any notion you had that you understood even the vaguest basics of the Java language.

On a slightly less cynical note, if you're looking to avoid many of the common design and implementation cock-ups, you might take a look at Effective Java, by the aforementioned Joshua Bloch, which has a wealth of decent advice on how to go about designing several of the important - but frequently badly written - aspects of writing components in Java, including a comprehensive explanation of how to properly implement the contract of equals() and hashCode(), and why you should avoid clone() like the plague.

Oh, and don't compare strings with the == operator.

14
votes

Saying that objects are passed by reference.

Actually, methods work only with copies of object references..which are passed by value.

Java only works with pass by value.

Also worth reading: Is-java-pass-by-reference?

10
votes

A small one: searching for a Java class on Google and expecting to find up to date information. Advice: always include the version number i.e search "inputstream 6" not "inputstream". Similarly, beware of tutorials on the net, lot of them are outdated.

10
votes

Bookmark javadocs: http://java.sun.com/javase/6/docs/api/index.html

Better yet, install them locally and bookmark the page on your local machine for faster lookup and offline browsing.

10
votes

I think another common beginner pitfall is re-inventing the wheel. That is, writing some (low-level) algorithm, data structure or utility yourself, when there would be (likely far better) implementation already offered by libraries.

For elaboration on this point, read Item 47 in Joshua Bloch's Effective Java (2nd ed): Know and use the libraries. (Read the whole book, while at it! ;-) I'll quote some of the main advice he gives:

By using a standard library, you take advantage of the experts who wrote it and the experience of those who used it before you.

[...] every programmer should be familiar with the contents of java.lang, java.util, and, to a lesser extent, java.io.

Specifically the Java Collections Framework, in java.util, will be immensely useful for any Java programmer, newbie or not; it definitely "reduces programming effort while increasing performance" as Mr Bloch says.

Along with libraries that come with the Java platform itself, a family of Java libraries worth mentioning is Apache Commons. It covers a lot of ground, is widely used, and often continues right where the standard libraries leave off. In addition, although I have yet to use them myself, it seems that Google has recently been putting out some high-quality Java libraries that supplement the Java platform, such as Google Collections (interesting article about it). Edit: now that I've acquainted myself better with Google Collections, I can say that the library is definitely worth looking into after learning the Java Collections framework; it seems like the perfect extension! Start with the Javalobby article I linked to, and also check out this presentation by Kevin Bourrillion, the main developer: part 1 & part 2.

9
votes

The difference between the scalar type int and the boxed type Integer is surprising to someone new to Java.

Java has always made a distinction between the "scalar" types, which are not classes: boolean (true/false), char (unsigned 16-bit), short (signed 16-bit), int (signed 32-bit), and long (signed 64-bit); and everything else which is a class and ultimately derived from the Object class.

The problem comes when you want to use something like a generic collection like a List. A List can contain anything that is derived from Object, but not scalar values. So in order to store int values into a List, you need to wrap them into an instance of a class called Integer that is derived from Object.

In old versions of Java, you also needed to explicitly get the value out of the Integer class using a .intValue() method call. In newer versions of Java, this conversion is called "unboxing" and is automatic in some situations.

Sun has a short page about autoboxing which is aimed toward a more experienced programmer but might be informative.

8
votes

Think about running FindBugs on your code (available as an Eclipse plugin). It can flag many common errors. As inspection tools go, I think it is a good one for beginners because it doesn't nitpick over inconsequential details.

8
votes

I think that the best "cheatcode" is "Don't be smart, write dumb code".

The terms are somewhat loaded but basically you want things to be simple when you write them, because then they will be simple to read when you come back to it later. Also these days the JVM is a LOT smarter than you are, and non-dumb code usually try to do something "more efficiently" which may prohibit the JVM from doing something even smarter.

Have a look at http://java.sun.com/developer/technicalArticles/Interviews/devinsight_1/

Please note: It is ok to write smart code, you just need to prove first it is necessary :)


EDIT: A few more things.

  • Write a lot of code. Practice makes perfect - always strive to do this in the best way possible. If you come back to your code later, you might have learned a thing or two since which allow you to perspective your earlier choices allowing you to make a better descision next time you have to make a choice. THIS INCLUDES DOCUMENTATION! Documentation is what allow others to use your code without understanding it in detail.

  • Read a lot of code. Set up your IDE so it allows you to see as much source as possible for what you work with. By using a JDK as the JVM in Eclipse the sources are automatically attached so you can SEE the source for whatever you happen to hit in a breakpoint. When including a jar from e.g. Apache in your code, include the sources so you can see what it does. It will help you some day that you can figure out WHY a certain thing happens and how to avoid it.

  • Work with peers. Other programmers on a similar level may provide input to a situiation - perhaps even just their listening to your explanation clarifies things in your mind - and you may also help them. By working together and evaluating together you can leverage each other.

  • The Java Tutorial from Sun covers a LOT of the Java libraries, and learning those covering the essential part of the runtime (java.lang, java.io) by heart and having read the rest (just to know what exists) will make you a more skilled programmer. You will know what is in your toolbox!

  • Participate in Stack Overflow. Writing good answers to questions (even if they have been answered but badly) will allow you to put your experiences into words, which is practice for writing documentation :)

7
votes

This may be a bit too basic of advice, so forgive me if I'm offending you for bringing it up, but I've seen way too much beginning Java code that throws the static keyword around freely, seemingly without regard for what it's for. So if you see a warning complaining about "static reference to non-static value" or some such thing, don't try to solve it by randomly placing static on an otherwise non-static thing, unless it makes sense to do so.

Here's a minor tip that you might have trouble searching for until you know the term for it: "package-private". In Java, there is the same public, protected, and private scopes that exist in other places like C++. You can read up on what they're for, if you don't already know. Note, however, that if you don't specify whether something is public, protected, or private, it's none of those things. It's package-private, and there's no keyword that specifies it except lack of a keyword. Package-private things act as private values to anything in another package and public to things that are in the same package.

One more random tip: Use packages. It's possible to not begin your .java files with a package com.whatever.foo; line, and if you're using command-line javac you'll find that it's nice that files lacking that line show up in your working directory, but it'll almost always end up being a pain later. And stop using command-line javac anyway. Use Eclipse.

7
votes

Java is a very straight forward language to start with, if you are already familiar with an imperative C sytle language. The deep issues are not specifically language related, but more broadly related to Statically (and strongly) typed, Single inheritance, OO languages.

I also humbly disagree with my Java brethren here and recommend that you learn to the basics using a text editor and the command line. That is were the specific gotchas of the JVM are most prominent.

Remember the most important distinction between Java and other languages: Java is both a language AND a platform.

You'll need to understand the notion of a classpath; the relationship between logical package structure and its (analogous) embodiment in the file system.

What will typing 'java', 'javac', etc. do when typed in the command line? Learn the fundamentals.

IDEs will completely paper over these fundamental issues of the Java platform.

I also recommend, if you are up to it, to read the Java language specification and (yes) the JVM specification. Make sure you grok classloaders and related issues when you begin your journey in Java if Mastery is what you are after.

5
votes

Use Eclipse for Java editing/development/debugging. Or some other IDE maybe, but for God's sake don't use Notepad & command line.

5
votes

There's always:

String a = "wow, not the same";
String b = "wow, not the same";
String c = new String("wow, not the same");
if (a == b) { //happens to evaluate to true, but you shouldn't do this
    ...
}
if (a == c) { //evaluates to false, which is why you shouldn't do it
    ...
}

//This is how you *should* do this
if (a.equals(b)) { //evaluates to true
    ...
}
if (a.equals(c)) { //evaluates to true
    ...
}
5
votes

Register to JavaBlackBelt and start doing tests over there. As you can see quickly from just browsing the front page, they cover just about anything from the most simple things to the incredibly advanced topics.

And don't be ashamed of failing any of the tests, failing just tells what you should learn more about before continuing :)

5
votes

Some mistakes I have seen people make who are experienced at programming but not at Java:

  1. Classes implicitly extend Object
  2. Classes implicitly import java.lang.*
  3. instanceof doesn't require a not null check
  4. Upcasting, e.g. ((Object)new Integer(1)).toString(), is almost never useful as it doesn't affect dynamic method selection
  5. Strings are immutable. There is no need to copy or clone them.
  6. Don't rely on the garbage collector or finalize() to perform resource (rather than memory) management. Resources, e.g. files, should be closed explicitly.
  7. Swing components, once displayed, should only be accessed from the AWT event thread (typically using SwingUtilities.invokeLater()).
  8. In general, be very, very careful when multiple threads share the same mutable/stateful objects. Either copy your objects first, or be prepared to use a while lot of synchronized blocks, wait() and notify().
5
votes

Obsessing over Design Patterns! I would not worry too much about design patterns to begin with. It is good if you are aware of their existence so that you will know what other members of your team talk about, but what is important right now is just exploring the Core Java APIs. When you feel comfortable with them I'd really put an effort into learning how to write clean and self-documenting code. This will save you a lot of time and effort in the future when you go back and need to remember what you were doing.

5
votes

Static finals can get baked into the class.

i.e.

public class Foo {
  public static final String A_STRING="A_STRING";
}

public class Bar { 
  public void printString() { System.out.println(Foo.A_STRING);}
}

Now compile both, then change "Foo" and recompile Foo but not Bar. Bar will still print out the old value of A_STRING. To experience this for yourself, run locally in eclipse, which silently recompiles all of your classes, and then do an incremental update on a server. Hey, where'd my changes go?

4
votes

what are the things Java does differently than other languages? (on a basic level)

On a basic level it's not different to other OOP language. However, comparing to plain procedural programming it's a whole new world... or a evolved one.

3
votes

I would have to say.

One of most common noob pitfalls phrases like "parameters on methods are always passed as reference, because Object variables are references, right?"

so when you see something like:

public void foo(String str){
      str="yeah, this should work!";
}

String str = "";
foo (str);

System.out.println(str);

You can hear a "Wait, WTF !" coming from a noob.

In my experience, java noobs don't know about StringBuffer / StringBuilder. Neither on inmutable objects.

2
votes

Another pitfall: figuring that a debugger is a debugger, and using the Eclipse debugger without spending time learning all about it.

Since you said you're using Eclipse, there's a series of 7 excellent video tutorials on the debugger here. I highly recommend spending the time (7*15 minutes) watching them.

2
votes

Avoid being more specific than you need to. You might be tempted to think of your storage object as a HashMap:

HashMap myStore = new HashMap();

But I would recommend thinking of it only as a Map (interface):

Map myStore = new Hashtable();

The rest of your code does not need to know how we implemented myStore, it just needs to know that myStore is some kind of Map. This way we can change the implementing type later (HashMap,Hashtable,...), and only one line of code will be affected.

And I chose Hashtable as an example, over HashMap, because Hashtable is thread-safe. In a multi-threaded app, this avoids the problem that two threads reading and changing the same HashMap concurrently can start throwing Exceptions.

2
votes

Make sure that you understand OOP instead of making everything static. And find out about stack overflow to ask questions :-).

2
votes

Combining equals() with autoboxing can get really crazy:

Integer X = 9000;
Integer Z = 9000;
short y = 9000;
boolean b1 = (X == Z);  
boolean b2 = (X == y);    
boolean b3 = (X.equals(Z));
boolean b4 = (X.equals(y));
System.out.println(b1 + " " + b2 + " " + b3 + " " + b4);

outputs:

false true true false
0
votes

From my experience, people new to Java never ever override equals, hashCode and toString methods, no mater what the objects purpose is. Also nobody ever bothers with setting up simple logging system. When I see System.out.println I feel like I'm ready to break fingers! But lot of seasoned coders are putting pin into thous tasks too.

On more advanced note get used to coding where Specs come first followed closely by unit testing - but this is more generic not just for Java. But again lots of people put pin into this.