انتقل إلى المحتوى
أمين أبوزيد
منشورBEG-007-L02

أسلوب Java: الشيفرة الوسيطة (bytecode) وJVM

  • الدرس 2 من 5
  • 11 دقيقة قراءة
  • مبتدئ
في هذا الدرس 11 موضوعات

هذا الدرس متاح حاليًا باللغة الإنجليزية فقط، ولم تُنشر نسخته العربية بعد.

Lesson Overview

The last lesson gave you two classic translators: a compiler that translates everything before running, and an interpreter that translates while running. Java does something in between. It compiles your source code, but not into machine code for one CPU. It compiles into an in-between form called bytecode, and a program called the Java Virtual Machine (JVM) then runs that bytecode on the real computer.

This design is the reason for Java's famous promise, "write once, run anywhere": you build once, and the same result runs on Windows, macOS, and Linux. We continue the translated-book analogy. Instead of translating your book into Spanish, French, and German separately, you translate it once into a neutral universal language, and each country has a local reader who knows that language and speaks it aloud to the local audience.

Why this matters: nearly everything you do in Java later, from building a project to deploying a backend service, passes through bytecode and the JVM. This lesson gives you the mental picture.

This lesson builds on L01 (compiler, interpreter, source code, machine code) and BEG-001 (CPU, operating system).

Learning Objectives

By the end of this lesson you will be able to:

  • Name the files and tools in the Java pipeline in order: .java file, javac, .class file, JVM.
  • Define bytecode and explain how it differs from source code and from machine code.
  • Explain what the JVM does.
  • Explain why the same .class file can run on Windows, macOS, and Linux.
  • Place Java correctly on the compiler/interpreter spectrum from L01.
  • Name what a .class file contains and why a text editor cannot show it as readable text.

Written Explanation

The pipeline in one picture

Java splits the journey from text to execution into two stages:

text
Hello.java  --javac-->  Hello.class  --JVM-->  output on screen
 (source)    compile     (bytecode)    run
  1. You write source code in a file ending in .java.
  2. The Java compiler, javac, translates it into one or more .class files. This is the compile stage, and it happens once, before the program runs.
  3. The JVM reads the .class file and runs it on the real machine. This is the run stage.

Two different programs are involved: javac for the first translation, and the JVM for running. In the terminal you start the JVM with the java command, which you will use in L04.

What bytecode is

Bytecode is a set of simple instructions designed for the JVM, not for any particular CPU. The Java Virtual Machine Specification describes a .class file as holding JVM instructions (bytecodes) plus a symbol table and other supporting information. That specification also calls the class file format hardware- and operating-system-independent.

Compare the three forms of the same program:

FormWritten forStored inReadable by people?
Source codePeople.java fileYes, it is text
BytecodeThe JVM.class fileNo, it is binary
Machine codeOne kind of CPUHeld in memory while the JVM runs the programNo

Bytecode sits between the other two. It is lower-level than your source, so it is easy for a program to process. But it is not tied to a particular CPU, so it can travel.

A small detail you can use as a fact to impress people: every valid class file begins with the four bytes with the hexadecimal value CAFEBABE, which the specification calls the magic number and uses to identify the file as a class file. You do not need to memorise it, but it shows that a .class file is a structured binary format and not plain text.

What the JVM does

The Java Virtual Machine is a program that runs bytecode. It is called "virtual" because it acts like a computer that has its own instruction set, and it implements that computer on top of the real one.

At a high level, the JVM:

  • loads .class files when the program needs them,
  • checks that the bytecode follows the JVM's rules before running it,
  • executes the instructions, so the program's output appears,
  • manages memory for the running program.

How a JVM executes the bytecode is flexible. The specification says the JVM is not inherently interpreted, and that it could be implemented in several ways. Real JVMs commonly mix interpreting the bytecode and translating busy parts of it into machine code while the program runs. You do not need the details now. The Middle-level JVM internals module covers them. What matters here: the JVM is the bridge between bytecode and the real CPU.

So where does Java fit on the L01 spectrum? It has a compile step (javac, early checking, a separate output file), and a running program (the JVM) that turns that output into action on the real CPU. It is both, and that is why "Java is compiled" and "Java is interpreted" are both only half-true.

Why "write once, run anywhere" works

Here is the reasoning chain:

  1. javac produces bytecode, which does not depend on a CPU or operating system.
  2. Each platform has its own JVM, built to run on that platform: one for Windows, one for macOS, one for Linux, and so on.
  3. All those JVMs understand the same bytecode.

So you compile once and take the .class file to any machine that has a JVM. In the book analogy: the neutral-language book is the .class file, and each local reader (JVM) turns it into the local speech. You never re-translate the book.

Contrast with a language that compiles straight to machine code. There, the program you build on Windows is generally not the file you would run on Linux, because the machine-code format and operating system conventions differ. You would build separately for each platform.

An honest limit on "anywhere": the promise covers the bytecode, not everything around it. A program that opens a file path written as C:\data\file.txt will still fail on Linux, because that path style belongs to Windows. And a machine needs a JVM installed, which L03 explains.

Many languages, one JVM

The JVM does not know the Java language. It knows only the class file format. The specification says any language whose functionality can be expressed in a valid class file can be hosted by the JVM. That is why other languages can also run on it. We use Java in this course, but the same JVM runs them all.

Why a .class file looks strange

Open a .class file in a text editor and you will see unreadable symbols, because the editor is trying to display binary data as text. This is expected, not a sign of damage. In the demo (L05) you will do it on purpose.

Examples

Example 1: the same file on two computers (simple)

Maya builds Greeter.class on her Windows laptop. She copies only that one file to Omar's Linux server, which has a JVM installed. Omar runs it, and it prints the same greeting. Nobody recompiled anything.

If Maya's program had been compiled to Windows machine code, the file would generally not run on the server. The neutral bytecode made the copy possible.

Example 2: following one program through the pipeline (practical)

Suppose the file Hello.java contains a program that prints a greeting. Here is each step and each file:

StepWho does itInputOutput
1. WriteYouYour ideasHello.java (text)
2. CompilejavacHello.javaHello.class (bytecode)
3. RunThe JVM (java command)Hello.classThe greeting on screen

If you edit Hello.java after step 2, Hello.class does not change by itself. The .class file is a snapshot of the source at the moment you compiled. To see your edit run, compile again. Forgetting this is a classic beginner stumble and L04 returns to it.

Example 3: a deployment decision (realistic)

A company develops a backend service on developers' Windows and macOS laptops, and runs it on Linux servers in a data centre.

  • The build produces bytecode packaged for the service.
  • The same build output is tested on laptops and then copied to the servers, where each server's JVM runs it.
  • When the operations team upgrades the servers' operating system or hardware, they install a suitable JVM and keep the same build output.

The team still has to test on the server: file paths, memory limits, and settings can differ even though the bytecode does not. "Run anywhere" means the code is portable, not that the environment is identical.

Backend Insight

Almost every Java backend you will build is delivered as bytecode: compiled classes bundled together and started on a server through a JVM. Several practical consequences follow:

  • Build once, deploy many times. Teams usually build the output once and deploy that same output to test, staging, and production, so what was tested is what runs.
  • The JVM is part of the server. A server needs a suitable JVM installed, and its version and settings affect how your service behaves, including memory use and start-up time.
  • Compile-time safety carries over. A lot of mistakes never reach production because javac refuses to produce bytecode for invalid source.

Later you will learn how build tools produce and package bytecode (BEG-054) and what the JVM does internally (MID-001).

Common Mistakes

Mistake 1: Thinking .class files contain machine code

  • Incorrect: "javac makes a program for my CPU."
  • Correct: "javac makes bytecode for the JVM. The JVM runs it on my CPU."

Mistake 2: Thinking the JVM is the compiler

javac compiles. The JVM runs. They are separate programs. Mixing them up leads to confusion about which tool to use when something fails.

Mistake 3: Expecting edits to source to change the running program automatically

The .class file is a snapshot. Change the .java file, then run javac again to produce a new .class, or you will keep running the old version.

Mistake 4: Reading "write once, run anywhere" as "no testing needed"

Bytecode is portable, but the operating system around it differs in paths, permissions, and installed software. Test in an environment that resembles where the program will run.

Exercises

Try each exercise yourself before opening the solutions.

Level A: Foundation

A1. Put these in the order they appear: .class file, .java file, program output.

أظهر الحل A1

A1. .java file, then .class file, then program output.

A2. Which program turns a .java file into a .class file, and which program runs the .class file?

أظهر الحل A2

A2. javac turns .java into .class. The JVM (started with the java command) runs the .class file.

A3. Is bytecode written for a particular CPU? Answer in one sentence.

أظهر الحل A3

A3. No. Bytecode is written for the JVM, which is why it does not depend on one CPU or operating system.

Level B: Application

B1. Explain, in three sentences, why one .class file can run on Windows and on Linux.

أظهر الحل B1

B1. javac compiles source into bytecode, which is not tied to any CPU or operating system. Each platform has its own JVM that can read that same bytecode. So the same .class file runs on every platform that has a JVM.

B2. You change one line in Hello.java but forget to run javac again, then run the program. Which version of the code runs, and why?

أظهر الحل B2

B2. The old version runs. The .class file is a snapshot made when you last compiled, and running it does not read the .java file. You must compile again.

B3. Fill in the table: for source code, bytecode, and machine code, say whether people can read it and whether it depends on a CPU type.

أظهر الحل B3

B3.

FormPeople can read it?Depends on CPU type?
Source codeYesNo
BytecodeNoNo
Machine codeNoYes

Level C: Challenge

C1. A friend says: "Java must be an interpreted language, because it needs a virtual machine to run." Write a short, polite reply that corrects this using the compile step.

أظهر الحل C1

C1. "Java does have a compile step: javac checks your source and produces bytecode before anything runs. The JVM then executes that bytecode, and may translate parts of it further while running. So Java combines both approaches instead of being purely interpreted."

C2. A teammate compiled on Windows and copied the .class to a Linux server. The program fails because it opens C:\reports\today.txt. Is this a failure of bytecode portability? Explain.

أظهر الحل C2

C2. No. The bytecode itself is portable, but the path C:\reports\today.txt is Windows-style and does not exist on Linux. The program makes an assumption about its environment. This is why "run anywhere" covers the bytecode and not everything the program touches.

Mini Challenge

Draw the Java pipeline as a labelled diagram on paper or in a text file, with the three files or outputs (source, bytecode, screen output), the two programs (javac and the JVM), and the words "compile time" and "run time" marking the two stages. Below the diagram, write two sentences answering: "If I give my .class file to a friend with a different operating system, what must they have in order to run it?"

Check your work: your diagram shows javac before the .class file and the JVM after it, and your answer mentions a JVM, not a compiler.

Summary & Next Lesson

Key takeaways

  • Java compiles source (.java) into bytecode (.class) with javac, and a JVM runs the bytecode.
  • Bytecode is for the JVM, not for a particular CPU. That is why the same .class file can run on different operating systems that each have a JVM.
  • The compile step catches rule-breaking mistakes early. The running stage is where runtime errors appear.
  • A .class file is a snapshot of the source at compile time. Recompile after editing.
  • "Run anywhere" covers the bytecode, not paths, permissions, or installed software.

Next lesson

You now know the pieces by role: compiler, bytecode, JVM. The next lesson, "JDK vs JRE vs JVM", sorts out three names that beginners confuse and tells you which one to install.

Self-check

  1. What is inside a .class file?
  2. Which tool produces the .class file?
  3. What does the JVM do?
  4. Why can one .class file run on several operating systems?
  5. You edited Hello.java. What must you do before running again?
أظهر الإجابات
  1. Bytecode, plus supporting information such as a symbol table.
  2. The compiler, javac.
  3. It loads and runs bytecode on the real machine.
  4. Bytecode does not depend on a CPU or operating system, and each platform has its own JVM that understands it.
  5. Compile it again with javac, so that a new .class file is produced.

References

التطبيق

طبّق هذا الدرس بمختبر الوحدة وتمارينها واختبارها.

المختبر والتمارين الاختبار

تعليم الدرس كمكتمل اختياري ويمكنك التراجع عنه في أي وقت. يبقى تقدمك محفوظًا في هذا المتصفح.

اكتب للبحث في المستويات والمراحل والوحدات والدروس.