The native Keyword in Java - Quiz
Total: 6 questions
1. What does the native keyword mean in Java?
What does the native keyword mean in Java?
native is a method modifier saying that the body of the method is implemented outside the JVM — in a compiled library (.dll, .so, .dylib) written in a language with a C-compatible ABI, usually C or C++, but Rust, Fortran or assembly work just as well. The Java side carries only the signature: there is no body and the declaration ends with a semicolon, as in public native int hashCode();
The keyword itself compiles nothing and links nothing. It does exactly one job: it lets a method be declared without a body and marks it as "the implementation arrives from elsewhere". Connecting that declaration to a real function at runtime is the job of JNI (Java Native Interface). People reach for native to use operating-system features the standard library does not expose, to reuse mature C/C++ libraries (codecs, cryptography, drivers) and inside the JDK itself.
2. How does JNI find the implementation of a native method, and what has to match?
How does JNI find the implementation of a native method, and what has to match?
Three things have to line up.
1. The library is loaded. Normally in a static initializer: System.loadLibrary("demo") searches java.library.path, while System.load("/absolute/path/libdemo.so") takes a full path. Do not write the lib prefix or the file extension inside loadLibrary() — the JVM adds the platform-specific ones itself.
2. The function name matches. The symbol is built by a strict rule: Java_ + the package with dots replaced by underscores + _ + the class name + _ + the method name. For com.example.Demo.sum() that is Java_com_example_Demo_sum.
3. The signature matches. The first parameter of the C function is always JNIEnv*; the second is jobject for an instance method or jclass for a static one; then come the declared parameters in JNI types (jint, jlong, jstring).
You never spell those names out by hand: the compiler generates the header with javac -h . Demo.java (the flag exists since JDK 8). The separate javah tool was deprecated in JDK 9 and removed in JDK 10.
3. Which modifiers can native be combined with, and where is native illegal?
Which modifiers can native be combined with, and where is native illegal?
Allowed: static (the C function then receives jclass instead of jobject as its second argument), synchronized (the monitor is acquired before control enters the native code), final and any access modifier — private, public, protected. A native method may declare throws and throw ordinary Java exceptions (the native side raises them through ThrowNew), and it takes part in reflection: Modifier.isNative(m.getModifiers()).
Illegal:
nativewith a body — native methods cannot have a body; the declaration ends with;;native+abstract— illegal combination of modifiers: both mean "no body here", but abstract promises an implementation in a subclass and native promises one in a library;nativeon a field or a class — modifier native not allowed here; the keyword applies to methods only;nativeon a constructor — move the native initialization into a separate native method and call it from the constructor;nativein an interface — interface methods are either abstract ordefault/staticwith a Java body.
4. Can a native method be overridden by a regular Java method in a subclass?
Can a native method be overridden by a regular Java method in a subclass?
Yes. Inheritance does not care where the implementation lives: native is not part of the method signature, so it plays no role in overriding. A native method can be overridden by a plain Java method, and a plain method of a superclass can be overridden by a native one.
The clearest example ships with the JDK: Object.hashCode() is declared native, while String overrides it with pure Java code. Reflection confirms it in two lines:
System.out.println(Modifier.isNative(
Object.class.getDeclaredMethod("hashCode").getModifiers())); // true
System.out.println(Modifier.isNative(
String.class.getDeclaredMethod("hashCode").getModifiers())); // false
5. Is a native method faster than a regular Java method, and where does native appear in the standard library?
Is a native method faster than a regular Java method, and where does native appear in the standard library?
No — native does not mean faster. Every crossing from Java into native code and back has a price: the JVM fixes up thread state, the JIT loses optimizations such as inlining across the call, and objects have to be reached through JNI functions. A small method called in a tight loop is frequently slower after being moved to C than the Java version it replaced.
At the same time you call native methods every day: Object.hashCode(), Object.getClass(), Object.clone(), System.arraycopy(), System.currentTimeMillis(), System.nanoTime(), Thread.currentThread(), Runtime.availableProcessors().
Many of them are annotated @IntrinsicCandidate in the JDK sources, which allows the HotSpot JIT to replace the call with hand-written machine code (an intrinsic) right at the call site. So in hot code System.arraycopy() or Math.sqrt() never travel the JNI path at all — here native only records the fact that there is no Java body.
6. What replaces JNI and native methods in modern Java?
What replaces JNI and native methods in modern Java?
The Foreign Function & Memory API in the java.lang.foreign package (Project Panama). It went through preview rounds in JDK 19—21 and was finalized in JDK 22 (JEP 454). It calls a function from a native library without a single line of C:
Linker linker = Linker.nativeLinker();
MethodHandle strlen = linker.downcallHandle(
linker.defaultLookup().find("strlen").orElseThrow(),
FunctionDescriptor.of(ValueLayout.JAVA_LONG, ValueLayout.ADDRESS));
try (Arena arena = Arena.ofConfined()) {
MemorySegment text = arena.allocateFrom("Hello, native!");
System.out.println((long) strlen.invoke(text)); // 14
}Compared with JNI: no C shim and no per-platform .so/.dll build of your own; many failures surface as Java exceptions instead of crashing the whole JVM; memory is released deterministically through Arena.
There is no urgency to rewrite existing JNI code — it is supported, and the native modifier remains part of the language. But since JDK 24 (JEP 472) both JNI and FFM count as restricted operations: the JVM prints a warning when a native library is loaded and when native methods are bound, silenced with --enable-native-access=ALL-UNNAMED.