From PHP to Java. Any advice? [closed]

I've been doing web application development for the last 3 years in PHP. I'm now on the verge to give Java a go. My last use of the language was nearly 8 years ago and was mostly academic.

I'm reasonably well acquainted with PHP's object model (version 5) and I have almost exclusively been coding in OO. I would now like to transport that experience and use it to develop in Java.

Where I'm coming from:

  • linux as a desktop and server
  • Vim/gVim + plugins as an editor
  • MySql for db
  • apache httpd
  • experience with a bunch of PHP frameworks, Zend+Doctrine being the ones I use most

What I've garnered so far about a move to Java:

  • I need an IDE: IntellijIDEA, NetBeans or Eclipse
  • I need to pick a development framework. Some recurrent names: Spring MVC, stripes, wicket.

Now I need some insight that could help make this transition smoother. But from the way people talk about it, Java seems to be an entirely new beast with its own ecosystem. It sounds as though moving to Ruby or Python would actually be easier, which is curious since, when I look at it, Java conceptually seems the closest to PHP, albeit stricter and precompiled.

As weird as this may sound, very few people have publicly documented their experience of such moves. I have searched google, amazon and stackoverflow for similar questions and the results leave to desire. I just can't believe that I would need to start the same as a newbie if I wanted to be productive as a web developer in Java fast.

Anybody is welcome to respond, but I somewhat think that people with some valuable experience in both languages would enrich this discussion the most.

  • What helped you get going quickly in Java?
  • What concepts are omnipresent in Java and absent from PHP and vice versa?
  • Some gotchas for PHP developers going Java.
  • How long before you felt the transition was complete?

Solution 1:

I wouldn't try to learn an IDE at the same time as learning a language. An easier transition would be to stick to your shell and habitual text editor, and use the following shell-friendly tools:

  • ant, for organising your project, running automated test suites, incremental compiles
  • BeanShell for interactive testing, trying things out quickly
  • A quick trick: javap from the commandline will give method signatures for any class in the standard library. Similar to php -r but gives more information since Java is typed.

The online documentation for Java is precise, professional, and consistent in tone and format. Unlike in PHP where all of the functions are in one flat namespace, the standard libraries in Java are class hierarchies. You've got to know your way around that standard library, which means knowing hierarchies + responsibilities: for example you've got to know that java.util.List is a subinterface of java.util.Collection with the addition of a concept of ordered entries. With that information in your head, a google search for java.util.List will take you to the Javadoc for the class, and the Javadoc will tell you exact method signatures and link you to a selection of concrete implementations.

Some miscellaneous distinctions:

  • Strings are sequences of characters rather than sequences of bytes. Absolutely the right way of doing it.
  • Systems produce and consume streams (of bytes or characters) rather than byte buffers. For example, if you wanted to filter the output in PHP, a standard practice is to ask ob_get_contents for a byte buffer then to transform the whole buffer. In Java, you add a filter to your servlet that transforms the output a byte or a character at a time. It's a bit imposing to work with initially but it's simpler and more Lego-like when you get used to it - your stream processor doesn't have to know where things come from and where they go.
  • Almost everything useful is an interface, and creating an instance of an interface can be tricky, non-standardised, and not always well-documented. In PHP, you can get up and running with XML with new DOMDocument(). In Java, org.w3c.dom.Document is an interface, so new() won't work. Javadoc is very precise about how interface instances behave once they come into existence, but it can be quite coy and prudish when you're trying to find out how an object is actually born. Very often, you'll have to look for tutorials and code examples and copy-paste a piece of boilerplate that gives you an instance of DOMDocument or java.sql.Connection or whatever. One reason frameworks like Spring are popular is that they separate out the ugly object-creation code and present you with a world where interface implementations are just magically there.

I actually switched in the opposite direction. I found that Java works very well in a large company where you might be working on a single component, handing it off to someone else who integrates that component into a larger system, which is then packaged and handed off to a separate operations team - that's where all this indirection and configurability (FactoryBuilderFactory type abstractions, web.xml files, etc) makes sense and does something useful. In a small company where the programmers are the ops personnel, Java is a lot more work. With Java, you'll have to get used to concepts like starting up the Java process, monitoring the Java process to make sure it stays up, monitoring the Java process to make sure that it doesn't go into a coma where it's alive but not responding, shutting down and restarting the Java process with minimal disruption when you're updating code, etc, etc. If you have separate ops personnel, that's fine, it's their job, they're very good at it. If you're a programmer, babysitting a Java process can be distracting and difficult to do well.

Solution 2:

Start with the Java Tutorial

http://java.sun.com/docs/books/tutorial/getStarted/index.html

Then go buy Head First Java

http://oreilly.com/catalog/9780596004651

It will get you going pretty quickly in the language which is essential regardless of what you want to do.