Most obviously, the J2ME programmer has access only to a reduced range of basic API classes. There is no built-in API support for file handling, RMI, JDBC, JNDI, multimedia (but this is changing), or the AWT/Swing user interface models. Some of this functionality is replaced by J2ME-specific classes. For example, the Java package javax.microedition.io.lcdui provides a class library for a simple widget-based user interface. javax.microedition.io provides an implementation of the HTTP protocol.
As well as these API and library differences, there are subtle differences in how J2ME JVMs work. For example, there is no JVM support for floating-point arithmetic (not even a double data type or Double class). Garbage collection is simplified - there are no soft references (yet), and finalize() methods are never called.
Of course, the limited memory availability in a J2ME device will require much more careful use of instances than J2SE developers will be used to. It will be necessary to re-use objects rather than creating new ones, and the developer will have to help the garbage collector more explicitly by nulling unwanted object references.