In my first post, switch-ing gears, I wrote about the differences between the switch statements in Java and PHP. Part of the difference was that in Java, you can’t switch on String type variables, but only on integers and another data type called an Enum, or an enumerated data type, which do not exist in PHP.

Enums are a data structure that contain a fixed set of constant members (called enumerators). The value of the Enum variable must be one of the defined constants. For example:

    public enum WeekDay {
        SUNDAY,MONDAY,TUESDAY,WEDNESDAY,THURSDAY,FRIDAY,SATURDAY;
    }

    WeekDay firstDay = WeekDay.SUNDAY;

Using any value that is not defined in the WeekDay enum, for example, “WeekDay.asdf”, will result in an error message stating that “asdf cannot be resolved or is not a field”. This gives us type safety, but I’ll come back to that in a minute.

You can sort of simulate the same type of functionality in PHP using constants in a standard class:

    public class WeekDay {
        public static const SUNDAY = 1;
        public static const MONDAY = 2;
        public static const TUESDAY = 3;
        public static const WEDNESDAY = 4;
        public static const THURSDAY = 5;
        public static const FRIDAY = 6;
        public static const SATURDAY = 7;
    }

    $firstDay = WeekDay::SUNDAY;

This will give you basically the same functionality as the Java enum, but with no type checking or safety. For example, if we have a function in our Java code that is expecting a parameter that must be one of the fields we defined in the WeekDay enum, we can express it like this:

    public void checkWeekDay(WeekDay day) {
        // ... do something to check the WeekDay
    }
 
    WeekDay day = WeekDay.SUNDAY;
    checkWeekDay(day);

This function will not accept any value except one of those defined in our WeekDay enum. If we were to use an integer instead, the integrity of our software is compromised, because we can not guarantee that the value of the integer passed to the function will be one of the allowed values (presumably a number from 1 to 7). Example:

    public String checkWeekDay(Integer day) {
        switch(day) {
            case 1:
                return "Sunday";
                break;
            case 2:
                return "Monday";
                break;
            case 3:
                return "Tuesday";
                break;
            case 4:
                return "Wednesday";
                break;
            case 5:
                return "Thursday";
                break;
            case 6:
                return "Friday";
                break;
            case 7:
                return "Saturday";
                break;
            default:
                throw new Exception("Integer value outside of acceptable range 1-7");
                break;
        }
    }
 
    Integer day = 450;
    try {
        checkWeekDay(day);
    } catch (Exception e) {
        // do something ugly here
    }

Yuck! Right?? Using our WeekDay enum, the error would have been caught before the program even compiled!

Another difference between the PHP and the Java is that using the enum data type in Java gives us the ability to list off all of the available members of the enum. In PHP we could technically use a ReflectionClass to list the class constants, but the code is much more involved than the Java equivalent. Let’s compare…

The Java:

    for (WeekDay wd : WeekDay.values()) {
        // this should print the names of the days of the week
        System.out.printf("Value: %s",wd.toString()); 
    }

The PHP:

    $r = new ReflectionClass('WeekDay');
    $constants = $r->getConstants();
    var_dump ($constants);

    /* 
     * Outputs:
     * Array
     * (
     *    ['SUNDAY'] => 1
     *    ['MONDAY'] => 2
     *    ['TUESDAY'] => 3
     *    ['WEDNESDAY'] => 4
     *    ['THURSDAY'] => 5
     *    ['FRIDAY'] => 6
     *    ['SATURDAY'] => 7
     * )
     *
     **/

This seems like a good solution, but in reality, this is overkill since the solution requires the instantiation of the entire ReflectionClass rather than accessing the properties of the class directly. Unfortunately, if you want to list class constants in PHP, this is the only method available.

Annotations in Java

28 Jun
2012

When I took over my first Java project, I noticed a lot of lines throughout the code that had no immediately discernible purpose. They looked like these:

    @Override
    @SuppressWarnings("unchecked")
    @Deprecated

… etc.

There were a lot of them. At first I wasn’t sure what they were or what they did. It took about 5 seconds on Google to learn that they were called “Annotations,” but that still wasn’t very helpful in figuring out their function.

In PHP, we also sometimes use the “@” symbol at the start of a line, but the purpose is very different and this confused me a bit. In PHP, when you see the @ in front of a line of code, its purpose is to suppress any warnings or errors that the line could potentially generate.

On an interesting side note, “@” in front of a line of PHP code can be used as a conditional statement. For example, if the file called ‘things.txt’ does not exist or can’t be read, the following script will exit with the text specified in the die() statement:

    @file('things.txt') or die('no way, man');

Similarly, the following two lines of code are almost-equivalent (except in certain cases like comparing boolean values – but I don’t really want to get that in-depth right now):

    1: if( isset($var) && $var === $value )
    2: if( @$var === $value )

Anyway, back to Java. It didn’t take long to realize that (@SuppressWarnings aside) annotations in Java serve a very different purpose from error suppression in PHP. It turns out that annotations provide information to the compiler or VM about the class, field, method, or other program element. Annotations don’t have a direct impact on the code, but they can be very useful. For example, the @SuppressWarnings annotation can be used to suppress certain types of warnings, while @Deprecated can be used in an interface to let the compiler know that a certain method should no longer be used. If the compiler detects that a @Deprecated method is being called, it can then warn the developer that a deprecated method has been called and should not be used.

Consider the following case, though:

    public interface Car { 
        /**
         * @deprecated use of drive()
         * use driveForward() or driveReverse() instead.
         */
        @Deprecated
        public void drive(); 
        public void driveForward();
        public void driveReverse();
    }

The @Deprecated annotation tells the compiler that use of the drive() method is deprecated, and shouldn’t be used. If it is found to be used, a warning will be generated, as in the following implementation of the Car interface:

    public class MyPorsche implements Car {
        public void drive() {}
        public void driveForward() {}
        public void driveReverse() {}
    }

But in a strange twist of fate, another annotation can suppress the warning – Guess which one!

    public class MyPorsche implements Car {
        @SuppressWarnings("deprecation")
        public void drive() {}
        public void driveForward() {}
        public void driveReverse() {}
    }

The third type of annotation used by the compiler is the @Override annotation, which simply tells the compiler that the annotated method should override a method with the same name in the super class. This can help developers identify typos in their code or classes and methods that don’t work as expected.

Of course, it is possible to take the use of annotations much further, to save yourself the trouble of writing common boilerplate code and configurations. You can even define your own annotations! I hope this basic introduction to annotations has been helpful for someone – There aren’t too many resources out there for a simple, easy-to-understand introduction.

One thing that I’ve been missing about PHP is the ability to specify default parameter values to functions. I’ve seen some threads online asking about this – PHP developers who are moving to Java and wondering how to provide default values for their method parameters. To be honest, it was one of the first things I Googled when I started writing Java code.

One of the most commonly provided answers I’ve seen is that if you need to specify a default value, you haven’t thought through your application well enough. To me, this isn’t entirely accurate, and I’ve been thinking about it a bit. In PHP, default values aren’t strictly necessary, but they can help make your development faster and allow you to update older functions with new parameters without touching the rest of your old code. In Java this problem is solved using method overriding, which I talked about in my post called Method Overriding.

Off the top of my head, I can’t think of an instance in Java where I would need to provide a default parameter. This is because Java is a strongly-typed language, and it is impossible for me to call a function without passing all of the necessary arguments. If I have a function called saveFile() that is expecting a MultipartFile and a String to be passed to it, and I fail to pass the String, I’ll get an error like this:

The method saveFile(MultipartFile, String) in the type UploadController is not applicable for the arguments (MultipartFile)

However, I could always override the function with one that only expects a MultiPart file!

I can’t override a method in PHP, but it will also give me a warning. The function and call:

function saveFile($file,$upload_path) {
    // do something to save the file
    return true;
}

$uploaded = saveFile($file);

Will generate the warning:

Warning: Missing argument 2 in call to saveFile()

But I can make PHP happy by using a default value for the upload path:

function saveFile($file,$upload_path = "/tmp/files") {
    // do something to save the file
    return true;
}

$uploaded = saveFile($file);

And all is well with the universe.

Method Overriding

27 Jun
2012

EDIT: It’s come to my attention that most of this post should more correctly be referred to as method overloading rather than overriding. The difference being that overriding usually refers to overriding a method from a super class, while overloading refers to overriding a method in the same class. Anyway, I will leave the post as-is for posterity :)

One of the things that I really like about Java so far is the ability to easily override methods. Not just methods in a parent class, but even methods within the same class.

Example:

class UserDao {

    public User findUser(Integer id) {
         User user;
         // do something to find the user by their id

         return user;
    }

    public User findUser(String username) {
         User user
         // do something to find the user by their username

         return user;
    }

}

Arguably, you can mimic this behaviour in PHP, using func_get_args, like this:

function findUser() {
   
    /* 
     *  We're only expecting one argument,
     *  return false for anything else 
     */

    if (func_num_args() !== 1) { return false };

    $user = null;

    $args = func_get_args();
    switch(gettype($args[0])) {
        case "integer":
            // $user = ... ; do something to find the user by id
            break;
        case "string":
        default:
            // $user = ... ; do something to find the user by username
            break;
    }

    return $user;    
}

$user = findUser(45);
$user = findUser("papa_smurf");

Even though this is technically possible, I personally prefer the Java-based method. It provides a bit more clarity for the developer, and it provides a more predictable result compared to the PHP. In the PHP example, a user is still free to pass any type of argument they want and will not receive any errors or warnings if their data is not received exactly as they assume it will be. In Java, the developer must pass the correct set of parameters for at least one of the method definitions.

Another thing that isn’t really clear in the PHP example is the case of multiple parameters. The code will grow quickly depending on how many arguments are passed to the function. And what about edge cases where one argument is expected in some cases but more than one argument is possible? The conditional code grows and grows, and will become difficult to maintain and then must be refactored (Or not, as the case may be :D ).

All things considered, I think the Java solution is much more elegant and intuitive as compared to the PHP.

switch-ing gears

26 Jun
2012

One of the first differences I ran into when I was starting with Java (besides the uncomfortable lack of dollar signs riddling my code) was the difference between PHP’s switch statement and the Java switch. In PHP, a switch statment is a simple comparison, and I could compare anything. It is equivalent to

if($condition) { … } elseif ($condition2) { … } etc…

For Example:

function best_cartoon($db_name = "db_Smurfs") {
    switch ($db_name) {
        case "db_Gadget":
            goGoGadgetWheels();
            break;
        case "db_Smurfs":
        default:
            throw new Exception("Azrael, you miserable cat!");
            break;
    }
}

Of course, this doesn’t exactly work as I expected in Java. In Java (at least before version 1.7), switch statements are a short form for a certain type of “if” statement, and can only be used to compare certain data types, like Integers and Enums. You can’t use a switch statement to compare strings, which is, of course, the very first thing I tried to do. However, I did find a nice workaround on stackoverflow that served my purpose:

    enum DBName {
	smurfs, gadget, UNKNOWN;
	public static DBName lookup(String dbName) {
	    try {
		return valueOf(dbName);
	    }
	    catch(Exception e) {
		return UNKNOWN;
	    }
	}
    }

    String dbName = "smurfs";
    
    switch(DBName.lookup(dbName)) {
        case gadget:
            goGoGadgetWheels();
            break;
        case smurfs:
        default:
            throw new Exception("Azrael, you miserable cat!");
            break;
    }

Of course, at this point, it’s probably easier to just use an “if” statement and save the trouble.

In a later post, I’ll go over more about what this ordeal has taught me about enum data types, which don’t exist in PHP.

PHP php ph…Java?

26 Jun
2012

Hey there!  My name is Tyler, and I’ve been developing websites since 1999, and using a standard LAMP stack since 2005. I’m more or less a Java newbie, but I’ve recently started a new job at which I am required to write websites in Java on a daily basis.  This blog is just a way for me to track my progress as a developer learning the basics of Java, and document my frustrations with being forced into using a strongly typed language.

Anyway, thanks for stopping by!  I hope you find this blog useful – My hope is that I can help at least one other person out there with their own transition from PHP to Java.  If I can do that, then I’ll consider this blog a success.   If you notice any glaring errors, please don’t be shy!  Leave a comment and correct me!

top