A compiler is a special program that translates code written in a high-level programming language (like C#, Java, or Kotlin) into a lower-level language that the computer can understand and execute.
- Lexical Analysis: The source code is broken down into tokens (keywords, variables, operators, etc.).
- Syntax Analysis: The compiler checks the code against the language's grammar rules to ensure it is syntactically correct.
- Semantic Analysis: It checks the meaning of the statements, ensuring that the operations are logically valid.
- Optimization: The compiler improves the performance of the code, such as reducing execution time or memory usage.
- Code Generation: Finally, the compiler generates the machine code or intermediate code.
The file produced by a compiler is often called a binary file or an executable file. Whereas you can read a source code and understand it, binary or executable files are not meant to be read by a human person. Only your computer can make sense of it.
In Java, the compiled code is known as bytecode, which runs on the Java Virtual Machine (JVM). In .NET, the compiled code is called Intermediate Language (IL) code, which runs on the Common Language Runtime (CLR).
-
C# Compiler (Roslyn): Compiles C# code into Intermediate Language (IL) code for the .NET framework.
-
Java Compiler (javac): Compiles Java code into bytecode, which is executed by the Java Virtual Machine (JVM).
-
Kotlin Compiler: Compiles Kotlin code into bytecode for the JVM, JavaScript, or native binaries using Kotlin/Native.
The .NET compiler is a crucial component of the .NET ecosystem, responsible for translating high-level code written in languages like C#, F#, and Visual Basic into Intermediate Language (IL) code.
Intermediate Language (IL), also known as Common Intermediate Language (CIL) or Microsoft Intermediate Language (MSIL), is a low-level programming language used by the .NET framework. It serves as the intermediate step between high-level source code and machine code.
-
Platform Independence: IL code is platform-independent, meaning it can be executed on any platform that has a compatible .NET runtime environment (e.g., Windows, Linux, macOS).
-
Language Interoperability: IL code can be generated from different high-level languages supported by .NET (e.g., C#, F#, Visual Basic). This allows for seamless interoperability between different .NET languages.
-
Just-In-Time (JIT) Compilation: At runtime, the Common Language Runtime (CLR) compiles IL code into native machine code specific to the platform's architecture using JIT compilation. This ensures that the application can run efficiently on the target machine.
-
Metadata: IL code is accompanied by rich metadata that describes the types, members, and other elements defined in the code. This metadata is used by the CLR for various runtime services, including type checking, security, and garbage collection.
-
Assembly: IL code, along with metadata and other resources, is packaged into an assembly. Assemblies are the building blocks of .NET applications and can be either executables (.exe) or libraries (.dll).
Some Useful links:
- Managed execution process: Refers to how the Common Language Runtime (CLR) handles the execution of .NET applications.
- Common type system (CTS): The common type system defines how types are declared, used, and managed in the common language runtime, and is also an important part of the runtime's support for cross-language integration.
- What is "managed code"?: When working with .NET, you'll often encounter the term "managed code". This article explains what managed code means and provides additional information around it.
- Native interoperability: The following articles show the various ways of doing "native interoperability" in .NET.
So, why we should choose and use .NET? see Why Choose .NET?
The Java compiler, known as javac
, is a key component of the Java Development Kit (JDK)
. Its primary role is to convert Java source code into bytecode, which can then be executed by the Java Virtual Machine (JVM)
The Java Runtime Environment, or JRE, is a software layer that runs on top of a computer’s operating system software and provides the class libraries and other resources that a specific Java program requires to run.
The JRE is one of three interrelated components for developing and running Java programs. The other two components are as follows:
-
The Java Development Kit, or JDK, is a set of tools for developing Java applications. Developers choose JDKs by Java version and by package or edition—Java Enterprise Edition (Java EE), Java Special Edition (Java SE) or Java Mobile Edition (Java ME). Every JDK always includes a compatible JRE because running a Java program is part of the process of developing a Java program.
-
The Java Virtual Machine, or JVM, runs live Java applications. Every JRE includes a default JRE, but developers can choose another that meets the specific resource needs of their applications. The JRE combines Java code created by using the JDK with the necessary libraries required to run it on a JVM and then creates an instance of the JVM that runs the resulting program. JVMs are available for multiple operating systems, and programs created with the JRE run on all of them. In this way, the Java Runtime Environment is what enables a Java program to run in any operating system without modification.
JVM is responsible for converting bytecode to machine-specific code and is necessary in both JDK and JRE. It is also platform-dependent and performs many functions, including memory management and security. In addition, JVM can run programs that are written in other programming languages that have been converted to Java bytecode.
Java Native Interface (JNI)
is often referred to in connection with JVM. JNI is a programming framework that enables Java code running in JVM to communicate with (that is, to call and be called by) applications that are associated with a piece of hardware and specific operating system platform. These applications are called native applications and can often be written in other languages. Native methods are used to move native code written in other languages into a Java application.
Java Development Kit, or JDK, is a software development kit that is a superset of JRE. It is the foundational component that enables Java application and Java applet development. It is platform-specific, so separate installers are needed for each operating system (for example, Mac, Unix, and Windows).
- Java Development Kit (JDK):
- Purpose: The JDK is used for developing Java applications. It includes tools for writing, compiling, and debugging Java code.
- Components: It contains the
Java compiler (javac)
,documentation generator (javadoc)
,archiver (jar)
, and theJRE
.
- Java Runtime Environment (JRE):
- Purpose: The JRE provides the environment required to run Java applications.
- Components: It includes the
JVM
andcore libraries
required for running Java applications.
- Java Virtual Machine (JVM):
- Purpose: The JVM executes
Java bytecode
, converting it into machine code that can be executed by the host system. - Components: It includes the
class loader
,bytecode verifier
, andexecution engine
.
- Purpose: The JVM executes
As a result:
Component | Description |
---|---|
JDK | For developing Java applications. |
JRE | For running Java applications. |
JVM | For executing Java bytecode on any platform. |
+--------------------------------------------------------------------------------+
| JDK (Java Development Kit) |
|--------------------------------------------------------------------------------|
| - javac (Java Compiler) |
| - javadoc (Documentation Generator) |
| - jar (Archiver) |
| - jdb (Debugger) |
| - Development Tools: |
| ├── javap (Disassembler) |
| ├── jps (Java Process Status Tool) |
| ├── jstat (Java Virtual Machine Statistics Monitoring Tool) |
| ├── jstack (Java Stack Trace) |
| ├── jmap (Memory Map) |
| ├── jshell (Java Shell/REPL) |
| └── Other development tools |
| |
| +-----------------------------------------------------------------------+ |
| | JRE (Java Runtime Environment) | |
| |-----------------------------------------------------------------------| |
| | - Core Libraries (JCL) | |
| | ├── java.lang, java.util, java.io, java.net, ... | |
| | └── other core libraries | |
| | - Native Libraries | |
| | └── Native methods implemented in C or C++. | |
| | - Runtime components | |
| | ├── Java Class Libraries | |
| | ├── Java Management Extensions (JMX) | |
| | ├── Java Naming and Directory Interface (JNDI) | |
| | ├── Java Sound API | |
| | ├── Java 2D API | |
| | ├── Java Web Start | |
| | | |
| | +---------------------------------------------------------------+ | |
| | | JVM (Java Virtual Machine) | | |
| | |---------------------------------------------------------------| | |
| | | - Class Loader | | |
| | | - Bytecode Verifier | | |
| | | - Execution Engine | | |
| | | ├── JInterpreter | | |
| | | └── Just-In-Time (JIT) Compiler | | |
| | | - Garbage Collector | | |
| | | - Java Native Interface (JNI) | | |
| | | - Runtime Data Areas | | |
| | | ├── Method Area | | |
| | | ├── Heap | | |
| | | ├── Stack | | |
| | | ├── Program Counter (PC) Register: | | |
| | | └── Native Method Stack | | |
| | +---------------------------------------------------------------+ | |
| +-----------------------------------------------------------------------+ |
+--------------------------------------------------------------------------------+
Some Useful links:
- Java Runtime Environment (JRE): What is the Java Runtime Environment (JRE)?
- JVM vs. JRE vs. JDK: What’s the difference?: How do JVM, JRE and JDK relate and work together in the Java development process?
- What is JDK, JRE, and JVM: Let’s take a closer look at JDK, JRE, and JVM to understand the function of each.
The Kotlin compiler, known as kotlinc
, is a tool that translates Kotlin source code into bytecode that can be executed on the Java Virtual Machine (JVM). It can also compile Kotlin code to JavaScript or native binaries, allowing Kotlin to be used in a wide range of platforms and applications.
Ahead-Of-Time (AOT) compilation is a technique where the source code is compiled into native machine code before it is executed. Unlike Just-In-Time (JIT) compilation, where code is compiled at runtime, AOT compilation translates the entire codebase into a standalone executable during the build process. This approach has several advantages, particularly in terms of performance and startup time.
- Faster Startup: Since the code is already compiled to native machine code, the application can start faster compared to JIT (Just-In-Time) compilation.
- Reduced Runtime Overhead: AOT eliminates the need for runtime compilation, reducing the overhead during execution.
- Smaller Footprint: The resulting native executable is typically smaller and more efficient.
- GraalVM: Kotlin can leverage GraalVM for AOT compilation, which provides advanced optimizations and performance improvements.
Language | AOT Compilation Tool/Technology | Description | Official Link |
---|---|---|---|
Java | GraalVM | High-performance runtime that provides AOT compilation, enabling Java applications to be compiled to native code | GraalVM |
.NET/C# | .NET Native | AOT compilation technology for UWP apps, improving performance and reducing memory usage | .NET Native |
ReadyToRun (R2R) | Compiles .NET assemblies ahead of time to improve startup performance | ReadyToRun | |
Kotlin | Kotlin/Native | Compiles Kotlin code to native binaries, enabling Kotlin applications to run on platforms without the JVM | Kotlin/Native |
GraalVM | Provides AOT compilation for Kotlin, enabling the creation of native executables from Kotlin code | GraalVM |
Subject | Java | .NET/C# | Kotlin | Official/Unofficial Link |
---|---|---|---|---|
Compiler | Java Compiler (javac ) |
C# Compiler (csc ) |
Kotlin Compiler (kotlinc ) |
Java Compiler (javac ), C# Compiler (csc ), Kotlin Compiler (kotlinc ) |
Standard Class Library | Java Standard Class Library (JCL) | .NET Standard Class Library (BCL) | Kotlin Standard Library | Java Class Library (JCL), .NET Standard Class Library (BCL), Kotlin Standard Library |
Development Kit | Java Development Kit (JDK) | .NET SDK | Kotlin Standard Library | Java Development Kit (JDK), .NET SDK, Kotlin Standard Library |
Runtime Environment | Java Runtime Environment (JRE) | .NET Runtime | Kotlin Runtime | Java Runtime Environment (JRE), .NET Runtime, Kotlin Runtime |
Virtual Machine | Java Virtual Machine (JVM) | Common Language Runtime (CLR) | Kotlin/JVM | Java Virtual Machine (JVM), Common Language Runtime (CLR), Kotlin/JVM |
Documentation Generator | Java Documentation Generator (javadoc ) |
XML Documentation Comments | Kotlin Documentation Comments (KDoc) | Java Documentation Generator (javadoc ), XML Documentation Comments, Kotlin Documentation Comments (KDoc) |
Archive Tool | Java Archive Tool (jar ) |
Assembly Packaging Tool (al ) |
Kotlin Archive Tool (jar ) |
Java Archive Tool (jar ), Assembly Packaging Tool (al ), Kotlin Archive Tool (jar ) |
Debugger | Java Debugger (jdb ) |
Visual Studio Debugger | Kotlin Debugger (kotlin-debugger ) |
Java Debugger (jdb ), Visual Studio Debugger, Kotlin Debugger (kotlin-debugger ) |
Disassembler | Java Disassembler (javap ) |
IL Disassembler (ildasm ) |
Kotlin Bytecode Disassembler | Java Disassembler (javap ), IL Disassembler (ildasm ), Kotlin Explorer |
Process Status Tool | Java Process Status Tool (jps ) |
Process Explorer | Kotlin Process Status Tool | Java Process Status Tool (jps ), Process Explorer, Kotlin Process Builders Tool |
Virtual Machine Statistics Tool | Java Virtual Machine Statistics Monitoring Tool (jstat ) |
Performance Monitor | Kotlin JVM Statistics Monitoring Tool | Java Virtual Machine Statistics Monitoring Tool (jstat ), Performance Diagnostic Tools, Kotlin JVM Statistics Monitoring Tool |
Stack Trace | Java Stack Trace (jstack ) |
Exception Stack Trace | Kotlin Stack Trace | Java Stack Trace (jstack ), Exception Stack Trace, Kotlin Stack Trace |
Memory Map | Java Memory Map (jmap ) |
Memory Profiler | IntelliJ Profiler | Java Memory Map (jmap ), Memory Profiler, IntelliJ Profiler |
Interactive Shell | Java Shell (jshell ) |
Interactive C# REPL (csi ) |
Kotlin REPL (kotlin-repl ) |
Java Shell (jshell ), Interactive C# REPL (csi ), Kotlin REPL (kotlin-repl ) |
Management Extensions | Java Management Extensions (JMX) | System.Diagnostics and Performance Counters | Kotlin Management Extensions | Java Management Extensions (JMX), System.Diagnostics and Performance Counters, Kotlin Management Extensions |
Native Interface | Java Native Interface (JNI) | Platform Invocation Services (P/Invoke) | Kotlin Native Interface (KNI) | Java Native Interface (JNI), Platform Invocation Services (P/Invoke), Kotlin Native Interface (KNI) |
Other Development Tools | Visual Studio, MSBuild, NuGet | IntelliJ IDEA, Gradle, Maven | IntelliJ IDEA, Gradle, Maven | Visual Studio, MSBuild, NuGet, IntelliJ IDEA, Gradle, Maven |
REPL: Stands for Read-Eval-Print Loop
In this example we explain how a simple program can be ran in C#, Java, and Kotlin:
let's consider this simple piece of code:
public class ConsoleApp
{
static void Main(string[] args)
{
System.Console.WriteLine("Hello, C# World!");
}
}
- Save this code in a file called:
ConsoleApp.cs
. - Run
csc ConsoleApp.cs
command inDeveloper Command Prompt
installed with Visual Studio:- This command will compile the source file and make an executable
ConsoleApp.exe
file for you.
- This command will compile the source file and make an executable
- Now, you can simple type
ConsoleApp.exe
in the command prompt to run the program.
The result would be:
C:\Users\SamPa\Desktop\Test>csc ConsoleApp.cs
Microsoft (R) Visual C# Compiler version 4.12.0-3.24572.7 (dfa7fc6b)
Copyright (C) Microsoft Corporation. All rights reserved.
C:\Users\SamPa\Desktop\Test>ConsoleApp.exe
Hello, C# World!
public class ConsoleApp {
public static void main(String... args) {
System.out.println("Hello, Java World!");
}
}
- Save this code in a file called:
ConsoleApp.java
. - Compile and Run source file with (JDK v11 and later):
Java ConsoleApp.java
will compile and run the program instantly (JDK v11 and later).- To make the
.class
file: simply runJavac ConsoleApp.java
will make you theConsoleApp.class
file.
The result would be:
PS C:\Users\SamPa\Desktop\Test> java ConsoleApp.java
Hello, Java World!
fun main() {
println("Hello, Kotlin World!")
}
- Save this code in a file called:
ConsoleApp.kt
. - Run
kotlinc ConsoleApp.kt
command to compile the source code. - Run
kotlin ConsoleAppKt.class
command to run the program.
The result would be:
PS C:\Users\SamPa\Desktop\Test> kotlinc ConsoleApp.kt
PS C:\Users\SamPa\Desktop\Test> kotlin ConsoleAppKT.class
Hello, Kotlin World!
Language | Compiler | Virtual Machine |
---|---|---|
C# | csc |
CLR |
Java | javac |
JVM (Java Virtual Machine) |
Kotlin | kotlinc |
JVM (Java Virtual Machine) |
| Command | Purpose |
|---------|----------------------------|
| dotnet | Command for CLR |
| Java | Command for JVM |
PS C:\Users\SamPa\Desktop\Test> dotnet --version
9.0.101
PS C:\Users\SamPa\Desktop\Test> java -version
openjdk version "23.0.1" 2024-10-15
OpenJDK Runtime Environment (build 23.0.1+11-39)
OpenJDK 64-Bit Server VM (build 23.0.1+11-39, mixed mode, sharing)