Chapter 8. Classes
A class declaration defines a new class and describes how it is implemented (§8.1).
A top level class (§7.6) is a class declared directly in a compilation unit.
A nested class is any class whose declaration occurs within the body of another class or interface declaration. A nested class may be a member class (§8.5, §9.5), a local class (§14.3), or an anonymous class (§15.9.5).
Some kinds of nested class are an inner class (§8.1.3), which is a class that can refer to enclosing class instances, local variables, and type variables.
An enum class (§8.9) is a class declared with abbreviated syntax that defines a small set of named class instances.
A record class (§8.10) is a class declared with abbreviated syntax that defines a simple aggregate of values.
This chapter discusses the common semantics of all classes. Details that are specific to particular kinds of classes are discussed in the sections dedicated to these constructs.
A class may be declared abstract (§8.1.1.1) and must be declared abstract if it is incompletely implemented; such a class cannot be instantiated, but can be extended by subclasses. A class may be declared final (§8.1.1.2), in which case it cannot have subclasses. If a class is declared public , then it can be referred to from code in any package of its module and potentially from code in other modules. Each class except Object is an extension of (that is, a subclass of) a single existing class (§8.1.4) and may implement interfaces (§8.1.5). Classes may be generic (§8.1.2), that is, they may declare type variables whose bindings may differ among different instances of the class.
Class declarations may be decorated with annotations (§9.7) just like any other kind of declaration.
The body of a class declares members (fields, methods, classes, and interfaces), instance and static initializers, and constructors (§8.1.6). The scope (§6.3) of a member (§8.2) is the entire body of the declaration of the class to which the member belongs. Field, method, member class, member interface, and constructor declarations may include the access modifiers public , protected , or private (§6.6). The members of a class include both declared and inherited members (§8.2). Newly declared fields can hide fields declared in a superclass or superinterface. Newly declared member classes and member interfaces can hide member classes and member interfaces declared in a superclass or superinterface. Newly declared methods can hide, implement, or override methods declared in a superclass or superinterface.
Field declarations (§8.3) describe class variables, which are incarnated once, and instance variables, which are freshly incarnated for each instance of the class. A field may be declared final (§8.3.1.2), in which case it can be assigned to only once. Any field declaration may include an initializer.
Member class declarations (§8.5) describe nested classes that are members of the surrounding class. Member classes may be static , in which case they have no access to the instance variables of the surrounding class; or they may be inner classes.
Member interface declarations (§8.5) describe nested interfaces that are members of the surrounding class.
Method declarations (§8.4) describe code that may be invoked by method invocation expressions (§15.12). A class method is invoked relative to the class; an instance method is invoked with respect to some particular object that is an instance of a class. A method whose declaration does not indicate how it is implemented must be declared abstract . A method may be declared final (§8.4.3.3), in which case it cannot be hidden or overridden. A method may be implemented by platform-dependent native code (§8.4.3.4). A synchronized method (§8.4.3.6) automatically locks an object before executing its body and automatically unlocks the object on return, as if by use of a synchronized statement (§14.19), thus allowing its activities to be synchronized with those of other threads (§17 (Threads and Locks)).
Method names may be overloaded (§8.4.9).
Instance initializers (§8.6) are blocks of executable code that may be used to help initialize an instance when it is created (§15.9).
Static initializers (§8.7) are blocks of executable code that may be used to help initialize a class.
Constructors (§8.8) are similar to methods, but cannot be invoked directly by a method call; they are used to initialize new class instances. Like methods, they may be overloaded (§8.8.8).
Write Native Methods in Java
- What Are Native Methods in Java
- Write Native Methods in Java Programs
This article takes you through various steps necessary to learn how to write native methods in Java programs.
What Are Native Methods in Java
The native keyword is a modifier in Java programming, used with methods only. It represents that this particular method is written in the native code via Java Native Interface (JNI).
The native (or foreign) methods are implemented in C, C++, or any other platform-dependent code.
[public/protected/private] native [returnType] youMethodName();
Write Native Methods in Java Programs
Listed below is the multi-step process to write native methods in Java programs:
Write the Java program containing the native method’s declaration and the main method to call the native method.
Compile the Java program with the main method and declare the specified native method.
Use javah with -jni flag to create the header file for the native method.
Write the code for the native method in the programming language you like, for instance, C/C++.
Create the shared library to compile the implementation and header files.
Finally, execute/run the Java Program.
Let’s follow all of these steps to call native methods in the Java program.
Write a Java Program
class nativeDemoClass //declaration of the native method public native void showMessage(); //load native C library static System.loadLibrary("nativedemoclass"); //lowercase of classname > //java main method public static void main (String[] args) nativeDemoClass demo = new nativeDemoClass(); demo.showMessage(); > >
We must include the native keyword as a method’s declaration part in the Java program if we implement the method in a programming language other than Java.
This native keyword tells the Java compiler that this specific method is a native programming language method. Remember, the declaration of a native method in the Java program provides the method signature only.
We have a static block that loads the native C library in which we have written the implementation of the showMessage() method. Have you noticed that we are passing a string to the System.loadLibrary() method?
Why is it so? It is because this static block from the nativeDemoClass class will load the appropriate library, named nativedemoclass .
Let’s move to the second step and compile the Java program.
Compile the Java Program
Use the command given below to compile the Java program.
javac nativeDemoClass.java
After successfully compiling the Java program, we get the nativeDemoClass.class file.
Create a Header File
Use the following command to create a header file.
Here, -h produces the C/C++ header files and places the generated file into the specified directory. We use dot ( . ) to keep the generated header file in the current directory.
javac -h . nativeDemoClass.java
You may find on the Internet that javah creates C/C++ header files, which was correct until JDK 8. According to the oracle, javah is deprecated now, but we have an alternative solution given above.
The nativeDemoClass.h file looks as follows. We do not edit this because it is a machine-generated file.
/* DO NOT EDIT THIS FILE - it is machine generated */ #include /* Header for class nativeDemoClass */ #ifndef _Included_nativeDemoClass #define _Included_nativeDemoClass #ifdef __cplusplus extern "C" #endif /* * Class: nativeDemoClass * Method: showMessage * Signature: ()V */ JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage (JNIEnv *, jobject); #ifdef __cplusplus > #endif #endif
The JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage declares the C function in this header file. We can have multiple function signatures if the nativeDemoClass has more native methods.
- Prefix as Java_
- The package name
- The class name
- native method’s name
Each section is separated by an underscore ( _ ), as shown graphically below:
Further, the JNIEnv* refers to the Java Native Interface environment that allows us to access the Java Native Interface (JNI) methods. The jobject references this object of Java programming.
Write the Native Code
#include #include "nativeDemoClass.h" #include JNIEXPORT void JNICALL Java_nativeDemoClass_showMessage(JNIEnv *env, jobject obj) printf("Hello world!\n"); return; >
The implementation of Java_nativeDemoClass_showMessage is pretty straightforward because we are only using a printf() statement to print Hello world . Remember, this .c file has three headers, jni.h , stdio.h , and nativeDemoClass.h created in the previous step.
Create the Shared Library
Use the following command to create the shared library. We must have build tools for visual studio to use the CL command.
cl -Ic:\java\jdk-17.0.2\include -Ic:\java\jdk-17.0.2\include\win32 -LD nativeDemoClassImp.c -Fenativedemoclass.dll
Remember, the Java program uses the following method to load the shared library, named nativedemoclass at run time.
System.loadLibrary("nativedemoclass");
Run the Java Program
Finally, use the command given below to run the Java program.
You will see Hello world! on the command line if you have done everything correctly.
Mehvish Ashiq is a former Java Programmer and a Data Science enthusiast who leverages her expertise to help others to learn and grow by creating interesting, useful, and reader-friendly content in Computer Programming, Data Science, and Technology.