Easy Tutorial
❮ Struct Size Python Print Without Newline ❯

Detailed Explanation of Java class.forName

Category Programming Technology

For most people, the first time they encounter the code class.forName(String className) is likely when using the JDBC method to connect to a database.

Example

import com.mysql.jdbc.Driver;
import java.sql.*;

public class JdbcDemo {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        String url = "jdbc:mysql://127.0.0.1:3306/mydb";
        String username = "root";
        String password = "redhat";
        Class.forName("com.mysql.jdbc.Driver");
        Connection connection = DriverManager.getConnection(url, username, password);
        String sql = "SELECT * FROM msg";
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        ResultSet resultSet = prepareStatement.executeQuery();
        resultSet.next();
        String address = resultSet.getString("address");
        System.out.println(address);
    }
}

After Class.forName is passed with com.mysql.jdbc.Driver, it knows that the database I am connecting to is MySQL. Why is that? Let's look at the source code:

@CallerSensitive
public static Class<?> forName(String className) throws ClassNotFoundException {
    Class<?> caller = Reflection.getCallerClass();
    return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
}

It is found that it calls the forName0 method, and then continue to trace and see:

private static native Class<?> forName0(String name, boolean initialize,
          ClassLoader loader,
          Class<?> caller)
 throws ClassNotFoundException;

It is a native method, and the source code can only end here. Let's also look at the official documentation description: https://docs.oracle.com/javase/7/docs/api/java/lang/Class.html#forName(java.lang.String)

>

Returns the Class object associated with the class or interface with the given string name, using the given class loader. Given the fully qualified name for a class or interface (in the same format returned by getName) this method attempts to locate, load, and link the class or interface. The specified class loader is used to load the class or interface. If the parameter loader is null, the class is loaded through the bootstrap class loader. The class is initialized only if the initialize parameter is true and if it has not been initialized earlier.

A rough translation would be: It returns a Class object for a given class or interface, and if no classloader is given, the root class loader is used. If the initalize parameter is passed as true, then the given class will be initialized if it has not been initialized before. When we first use JDBC, the parameter passed is com.mysql.jdbc.Driver. This means that this class will be initialized. Let's take a look at the contents of this class:

public class Driver extends NonRegisteringDriver implements java.sql.Driver {

static {
    try {
        java.sql.DriverManager.registerDriver(new Driver());
    } catch (SQLException E) {
        throw new RuntimeException("Can't register driver!");
    }
}


    public Driver() throws SQLException {
    // Required for Class.forName().newInstance()
    }
}

We find that this class is also very simple. A constructor and a static code block. We know that when a class is initialized, the content of the static code block will be executed. That is to say, our Class.forName and directly writing DriverManager.registerDriver(new Driver) are functionally equivalent. Let's try changing to this method:

public class JdbcDemo {
    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        String url = "jdbc:mysql://127.0.0.1:3306/mydb";
        String username = "root";
        String password = "redhat";
        //Class.forName("com.mysql.jdbc.Driver");
        DriverManager.registerDriver(new Driver());
        Connection connection = DriverManager.getConnection(url, username, password);
        String sql = "SELECT * FROM msg";
        PreparedStatement prepareStatement = connection.prepareStatement(sql);
        ResultSet resultSet = prepareStatement.executeQuery();
        resultSet.next();
        String address = resultSet.getString("address");
        System.out.println(address);
    }
}

It is found that the code is still executed normally.

In summary: The function of the Class.forName method is to initialize the given class. And the MySQL Driver class we provided has registered the driver through JDBC's DriverManager in its static code block. We can also directly use JDBC's driver manager to register the MySQL driver, thus replacing the use of Class.forName.

>

Original article link: http://linuxsogood.org/1580.html

#

-

** CTCE

** 112 By this point, without explanation, readers will understand why the Class.forName('driver class name') method is executed when connecting to a database using the JDBC method: it loads the driver class file into memory, creates a Class instance that describes the structure of this driver class, and initializes this driver class, so that the JVM can use it. This is the meaning of the Class.forName() method.

Friends with database development experience will find that when we load the database driver package, why is it that some do not call the newInstance() method? That is, some JDBC connection to the database is written as Class.forName(xxx.xx.xx); while some are: Class.forName(xxx.xx.xx).newInstance(); why are there these two ways of writing?

As mentioned earlier, the role of Class.forName(""); is to require the JVM to search and load the specified class. If there is a static initializer in the class, the JVM will inevitably execute the static code segment of the class. In the JDBC specification, it is clearly required that this Driver class must register itself to the DriverManager, that is, the code of any JDBC Driver's Driver class must be similar to the following:

public class MyJDBCDriver implements Driver { 
    static { 
        DriverManager.registerDriver(new MyJDBCDriver()); 
    } 
}

Since the registration has already been made in the static initializer, we only need Class.forName(XXX.XXX); when using JDBC.

** CTCE

* 112**[email protected]

** Reference link

-

** Fangzi

* 465**[email protected]

** Reference link

The difference between Class.forName() and xxx.class

All classes are dynamically loaded into the JVM when they are used for the first time. When the program creates the first reference to a static member of a class, that class is loaded. This also proves that the constructor is also a static method of the class, even if there is no static keyword before the constructor. Therefore, creating an object of a class using the new operator is also considered a reference to a static member of the class.

Therefore, a Java program is not fully loaded before it starts running, its various parts are loaded as needed.

The class loader first checks whether the Class object of this class has been loaded. If it has not been loaded, the default class loader will look for the .class file according to the class name. When the bytecode of this class is loaded, they will be verified to ensure that they have not been corrupted.

The Class object is only loaded when needed. Static initialization is performed when the class is loaded. Class.forName(), this method is a static member of the Class class. The Class object, like other objects, can be obtained and operated on its reference. forName() is a method to obtain a reference to the Class object. It takes a String containing the textual name of the target class as an input parameter and returns a reference to a Class object. If forName() finds that a class has not been loaded, it will actively load this class, and during the loading process, the static clause of the class will be executed.

Java also provides another method to generate a reference to the Class object, that is, using the class literal constant. In the form of: xxx.class. However, when creating a reference to the Class object in this form, the Class object is not automatically initialized. Initialization is delayed until the first reference to a static method or a non-constant static field is made.

public class Initable {  
    static final int staticFinal = 47;  
    static final int staticFianl2 = ClassInitialization.rand.nextInt(1000);  
    static {  
        System.out.println("Initializing Initable");  
    }  
}
public class Initable2 {  
    static int staticNonFinal = 147;  
    static {  
        System.out.println("Initializing Initable2");  
    }  
}
public class Initable3 {  
    static int staticNonFinal = 74;  
    static {  
        System.out.println("Initializing Initable3");  
    }  
}

``` public class ClassInitialization {
public static Random rand = new Random(47);
public static void main(String[] args) throws ClassNotFoundException {
Class initable = Initable.class;
System.out.println("after creating Initable ref");
//Does not trigger initialization
System.out.println(Initable.staticFinal);
//Does trigger initialization
System.out.println(Initable.staticFianl2);
//Does trigger initialization
System.out.println(Initable2.staticNonFinal);

❮ Struct Size Python Print Without Newline ❯