How do I use Generics in Java programming?

In this post we are going to talk about one of Java programming language feature called as generics. Generics is a feature introduced in JDK 5.0. The generics feature allow you to abstract over types. What does it mean? It means that you can create a class or method that can work for a type assigned to it. You’ll see a lot of use of generics when you are working with Java Collections. But of course generics can be used for doing other things in you program.

To illustrate this feature let us begin by creating a code when the generics are not yet available in Java to see what problem it is trying to solve.

List data = new ArrayList();
data.add("John Doe");
String name = (String) data.get(0);

Here are the things we can see from the code above. First we create an ArrayList and call it data. This variable actually can hold any Java objects in it. On the second line we add a string to this list. And finally on the third line we get the data back from the list. One thing you see here is that you need to cast the object read out from the list. Because the list doesn’t know what type to return other than java.lang.Object.

If you look to the definition of the List’s add() and get() method prior to JDK 5.0 you’ll see that the add() method will accept Object as argument and the get() method also returns Object.

Now, let say your friend try to use your class, and he tries to add another object the list. He adds the following lines.

data.add(new Date());
String name = (String) data.get(0);

This code will actually compile just fine. The add() method will work because Date extends Object. And the get() method will also compile without any error. But when we execute the program we will get a runtime error saying that it cannot cast a Date object into type of String.

Exception in thread "main" java.lang.ClassCastException: java.util.Date cannot be cast to java.lang.String

So how do you protect your friend from making this mistake? You can use generics. You can tell what the list should store by defining the type for the list. This way you will get a compiled time check to make sure that you are adding the correct data to the list. So, your code will look like the following.

List<String> data = new ArrayList<String>();
data.add("John Doe");
String name = data.get(0);

In this generic version of the code snippet you see that now we declare the list to store an object of type String. If you tried to add a Date into the list you’ll get a compiled time error. Your IDE will mark the line as error. The other benefit is that you don’t have to do the cast anymore. Generics reduce the clutters in your code by removing the unwanted cast operator from your code.

Actually if you are working on the JDK 7, you can simplify the variable declaration using diamond operator. So you can write it like.

List<String> data = new ArrayList<>();

I hope this will give you the basic understanding of generics and how to use it in your day-to-day working with your Java projects.

How to use Preferences API to store program configurations?

The Preferences API provided in the java.util.prefs package can be used to store and retrieve application configurations. The main class is the Preferences class. Using this class you can manage the preference data such as storing, retrieving, removing and clearing the preference data.

Preferences are key-value pairs of data. You can store a string, int, boolean and other primitive data type. You can use the get() method to retrieve value associated with a key from preference node and the put() method to store a value associated with a key in the preference node. To remove a value associated with a key from preference node you can use the remove() method. And if you want to clear the keys from the preference node you can use the clear() method.

The actual storage of these preference data is dependent on the platform. For example in Windows OSes it stored in the Windows Registry. What you have to know that this Preferences API is not intended to use for storing application data, you will only use it to store configurations of your applications.

Let’s see an example of using the Preferences API.

package org.kodejava.util.prefs;

import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;

public class PreferencesExample {
    public static void main(String[] args) {
        PreferencesExample demo = new PreferencesExample();
        demo.setPreferences();
    }

    private void setPreferences() {
        // Define a node to store the preference data.
        Preferences pref = Preferences.userRoot().node(getClass().getName());

        String key1 = "KEY1";
        String key2 = "KEY2";
        String key3 = "KEY3";

        // Read the value of KEY1, return an empty string if the value
        // hasn't been set previously.
        String key1Value = pref.get(key1, "");
        System.out.println("KEY1: " + key1Value);

        // Read the value of KEY2 as an integer, if the value hasn't
        // been set previously return -1.
        int key2Value = pref.getInt(key2, -1);
        System.out.println("KEY2: " + key2Value);

        // Read the value of KEY3, return true if no value was set
        // previously.
        boolean key3Value = pref.getBoolean(key3, true);
        System.out.println("KEY3: " + key3Value);

        // Set the values for all the preference key above.
        if (key1Value.equals("")) {
            pref.put(key1, "January");
        }
        if (key2Value == -1) {
            pref.putInt(key2, 1000);
        }
        if (key3Value) {
            pref.putBoolean(key3, false);
        }

        printKeys(pref);

        // Remove KEY1 from the preference data.
        pref.remove(key1);
        printKeys(pref);

        try {
            // Remove all preference data of this node.
            pref.clear();
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }

        printKeys(pref);
    }

    /**
     * Print Keys in the preference node.
     * @param pref Preference node.
     */
    private void printKeys(Preferences pref) {
        System.out.println("PreferencesExample.printKeys");
        try {
            String[] keys = pref.keys();
            for (String key : keys) {
                System.out.println("Key = " + key);
            }
        } catch (BackingStoreException e) {
            e.printStackTrace();
        }
        System.out.println("============================");
    }
}

Here are the output you’ll get when running the example above:

KEY1: 
KEY2: -1
KEY3: true
PreferencesExample.printKeys
Key = KEY1
Key = KEY2
Key = KEY3
============================
PreferencesExample.printKeys
Key = KEY2
Key = KEY3
============================
PreferencesExample.printKeys
============================

How do I create MySQL database programmatically in Java?

There are times that you might need to create a database or tables right after you run your program instead of manually creating it. In this example, I will show you how you can do this using JDBC and MySQL database. The first thing we need to do as usual when creating a JDBC program is to define a JDBC URL. One thing that you’ll notice here is that we don’t define the database name in the URL. So the URL will be like jdbc:mysql://localhost.

After defining the URL, we need to create a connection to the database. We issued the DriverManager.getConnection() method and pass the URL, username and password as the arguments. The next step is to create a PreparedStatement. When we call the preparedStatement() method we pass an SQL command to create the database, which is CREATE DATABASE IF NOT EXISTS demodb. This will create a new database if there is no database with demodb name exists in the database. Finally, call the PreparedStatement‘s execute() method

Now you can try for your self, start typing the following code snippet in your text editor or IDE, and execute it to create the database.

package org.kodejava.jdbc;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;

public class CreateMySQLDatabaseExample {
    public static void main(String[] args) {
        // Defines the JDBC URL. As you can see, we are not specifying
        // the database name in the URL.
        String url = "jdbc:mysql://localhost";

        // Defines username and password to connect to database server.
        String username = "root";
        String password = "root";

        // SQL command to create a database in MySQL.
        String sql = "CREATE DATABASE IF NOT EXISTS demodb";

        try (Connection conn = DriverManager.getConnection(url, username, password);
             PreparedStatement stmt = conn.prepareStatement(sql)) {

            stmt.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

After you are executing the code snippet above you will find a new database named demodb created in your MySQL database server.

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central

How do I set up JAVA_HOME and Path variables in Windows?

Setting up a JAVA_HOME and Path variables is the second thing you’ll need to do after installing a JDK (Java Development Kit). Although this is not required by Java itself, it is commonly use by other application. For instance then Apache Tomcat web application server and other application server will need it. Or we might need it if we want to compile or running our Java classes from the command prompt. It helps us to organize the default JDK and the execution path.

So here are the steps that we’ll need to do to configure the JAVA_HOME and Path variable on a Windows operating system.

Step 1. Finding the location of our JDK installation directory. If we already know where we have installed the JDK continue to the Step 2.

  1. The JDK usually installed in the C:\Program Files\Java directory by default.
  2. Under this directory we can find one or more versions of installed JDK, for examples I have jdk-14 and jdk-17. Just choose the default one we’re going to use.

Step 2. Setting JAVA_HOME variable

After we know the location of your JDK installation, we can copy the directory location from the Windows Explorer address bar.

  1. Open Windows Explorer
  2. Right-Click the Computer and select the Properties menu.
  3. Click Advanced system settings and the System Properties windows will be shown.
  4. Select the Advance tab.
  5. Click the Environment Variables button.
  6. A new Environment Variables window will be shown.
  7. Under the System Variables, click the New button to create a new environment variable.
  8. Enter the variable name as JAVA_HOME, all letters are in uppercase.
  9. In the variable value enter the JDK installation path you’ve copy above.
  10. Click OK.

Step 3. Setting the Path variable

After we’ve set the JAVA_HOME variable, now we can update the Path variable.

  1. In the Environment Variables window, under the System Variables section find a variable named Path.
  2. If we don’t have the Path variable we need to add one using the New button.
  3. If we already have the Path variable we’ll need to update its value, click Edit button to update.
  4. Add %JAVA_HOME%\bin; to the beginning of the Path variable value.
  5. Press OK to when we are done.
  6. Press another OK to close the Environment Variables window.

Step 4. Check to see if the settings work

  1. Open your Windows Command Prompt.
  2. Type java -version in the command line.
  3. If everything was set correctly we’ll see the running version of your installed Java JDK.

As an example on my Windows Command Prompt I have something like:

D:\>java -version
java version "17" 2021-09-14 LTS
Java(TM) SE Runtime Environment (build 17+35-LTS-2724)
Java HotSpot(TM) 64-Bit Server VM (build 17+35-LTS-2724, mixed mode, sharing)

If you don’t see the correct output, for instance you get an error like “‘java’ is not recognized as an internal or external command, operable program or batch file.”, please retry the steps described above. Enjoy your new adventure with Java programming. Happy coding!

How to establish connection to a database using Properties object?

In the following code snippet, you will see how to pass some connection arguments when connecting to a database. To do this, we can use the java.util.Properties class. We can put some key value pairs as a connection arguments to the Properties object
before we pass this information into the DriverManager class.

Let’s see the example below:

package org.kodejava.jdbc;

import java.sql.*;
import java.util.Properties;

public class GetConnectionWithProperties {
    private static final String URL = "jdbc:mysql://localhost/kodejava";
    private static final String USERNAME = "kodejava";
    private static final String PASSWORD = "s3cr*t";

    public static void main(String[] args) {
        GetConnectionWithProperties demo = new GetConnectionWithProperties();
        try (Connection connection = demo.getConnection()) {
            // do something with the connection.
            Statement stmt = connection.createStatement();
            ResultSet rs = stmt.executeQuery("SELECT * FROM product");
            while (rs.next()) {
                System.out.println("Code = " + rs.getString("code"));
                System.out.println("Name = " + rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }

    private Connection getConnection() throws SQLException {
        Properties connectionProps = new Properties();
        connectionProps.put("user", USERNAME);
        connectionProps.put("password", PASSWORD);

        Connection connection = DriverManager.getConnection(URL, connectionProps);
        System.out.println("Connected to database.");
        return connection;
    }
}

Maven Dependencies

<dependency>
    <groupId>com.mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>8.4.0</version>
</dependency>

Maven Central