By the normal definition of a memory leak, Java does not have them due to Garbage collection. If we, however, expand the definition a little bit to "Objects the program does not need anymore, but are not garbage-collectible", then there are two scenarios I can think of where such "leaks" could arise.
Scenario 1: record all objects of a class ever created
This example has an artificial taste and is often seen in the context of an exercise. Suppose we want to store every instance of a certain class ever created. This can be achived through a static colleciton:
public class RecordMe {
  private static final List<RecordMe> created = new ArrayList<RecordMe>();
  ...
  private final int someValue;
  private RecordMe(final int someValue) {
    this.someValue = someValue;
  }
  public static RecordMe of(final int someValue) {
    RecordMe me = new RecordMe(someValue);
    created.add(me);
    return me;
  }
  public static List<RecordMe> instances() {
    return Collections.unmodifiableList(created);
  }
}
As soon as an instance of RecordMe is created, it can never be garbage-collected because it will always be referenced through the static list.
The fix would be to check the list before creating a new instance of RecordMe or use List<WeakReference<RecordMe>> (and clean this list from time to time).
Scenario 2: Leaks through inner classes
As we know, a non-staitc inner class holds an implicit reference to the object it was created from. Let's take a look on an extreme example.
public class MemoryTest {
  // data has a size of a little over 512 MB.
  private final byte[] data = new byte[1024 * 1024 * 512];
  private final Field field;
  public class Field {
  }
  public MemoryTest() {
    this.field = new Field();
  }
  public Field getField() {
    return this.field;
  }
  public static void main(String... args) {
    MemoryTest test = new MemoryTest();
    Field fieldOne = test.getField();
    test = null;
    test = new MemoryTest();
  }
}
If we execute this code with java -Xmx800m MemoryTest, it will throw an OutOfMemoryException. Examples of this sizes are unrealistic in the real, but in smaller sizes and with enough instances, this can also lead to issues. Take, for example, Java's HashMap-implementation. Method keySet() returns an instance of a non-static, inner class. As long as one holds instances to those inner classes, the HashMap cannot be garbage-collected.