Bytecode, object code, and machine code are code representations distinguished mainly by who is meant to read them.

Learning Question

What is the difference between bytecode, object code, and machine code?

These names are easy to blur because all of them can be described as “lower-level code.”

The useful distinction is not only how low-level they feel.

The useful distinction is:

Which reader or execution environment is this representation meant for?

Bytecode, object code, and machine code are all byte-based representations, but they occupy different places in the chain from source files to running behavior.

Comparison

RepresentationMain ReaderTypical ContainerDirectly CPU-executed?
source codecompiler, interpreter, humans.java, .c, .jsno
bytecodevirtual machine.classno, not directly
object codelinker and toolchain.o, .objcontains CPU code but not necessarily loadable as a program
machine code in executableOS loader and CPUELF, PE, Mach-Oyes, after loading into a process

This table is simplified, but it preserves the main boundaries.

The container file matters.

The intended reader matters.

The runtime context matters.

Bytecode

Bytecode is an intermediate instruction representation for a virtual machine.

Java bytecode is read by the JVM.

It is below Java source code because it is no longer written as Java source text.

It is not the same as CPU machine code because a physical CPU does not directly execute Java bytecode as its normal instruction set.

A JVM may:

  • interpret bytecode
  • verify bytecode
  • link symbolic references
  • compile hot bytecode to machine code later
  • optimize or deoptimize runtime execution

The class file remains a JVM-facing artifact.

For deeper class-file details, see What a Class File Contains.

Object Code

Object code is compiled code and metadata stored in an object file.

In a C-oriented toolchain, an object file often contains:

  • machine-code fragments for compiled functions
  • symbol information
  • relocation information
  • section metadata
  • references that may need linking

An object file can contain CPU instruction bytes, but it is usually not a complete executable program by itself.

It may still need a linker to connect symbols, arrange sections, resolve relocations, and produce an executable file.

The key boundary is:

Object files can contain machine-code pieces without being final launchable program files.

For deeper C build details, see From Source Code to Executable File.

Machine Code

Machine code is instruction bytes defined by a real CPU architecture.

A CPU can fetch, decode, and execute those instruction bytes when they are placed in an executable memory context.

Machine code is still not enough by itself for ordinary user programs.

In normal operating-system environments, machine-code bytes need to be packaged, loaded, mapped into a process, and given runtime state before they execute.

That means the question is not only:

Are these bytes CPU instructions?

It is also:

Are these bytes in a context where the CPU is supposed to execute them?

CPU Instruction Set Versus JVM Instruction Set

The JVM defines bytecode instructions for a virtual machine execution model.

A CPU architecture defines machine instructions for a physical processor family.

These are different instruction sets.

For example:

  • JVM bytecode instructions operate in the JVM’s stack-frame and class-file model.
  • CPU machine instructions operate in the CPU’s register, memory, and instruction-set model.

The JVM may eventually compile bytecode into machine code, but that does not make the original class file the same thing as a native executable.

Object File Versus Executable File

An object file and an executable file can both contain machine-code-related bytes.

They serve different roles.

FileRole
object filecompiled piece for the linker and toolchain
executable filelinked loadable program artifact for the operating-system environment

This distinction matters because a tool can inspect object code without launching a process.

The program runs only after an executable or runtime target is launched and given process state.

Compiled Artifact Versus Running Process

Bytecode, object code, and machine code in files are stored representations.

They do not automatically become running behavior because they exist on disk.

Runtime behavior needs an execution context:

  • JVM process for Java bytecode
  • OS process for native executables
  • executable memory and CPU state for machine instructions
  • loader or runtime work to prepare the environment

This keeps the collection’s central model intact:

Bytes need an interpreter, loader, runtime, or CPU context before they produce behavior.

What These Code Forms Separate

This chapter does not enumerate Java bytecode instructions, object-file sections, relocation formats, assembly syntax, CPU opcodes, or JIT compiler internals.

It only separates the representation categories needed for the rest of the collection.

Code Form Rule To Carry Forward

Classify code representations by their intended reader:

  • source code: humans and language tools
  • bytecode: virtual machine
  • object code: linker and toolchain
  • machine code in executable memory: CPU
  • executable file: operating-system loader and runtime environment before CPU execution

When inspecting a code artifact, ask:

Is this source text, virtual-machine bytecode, a linkable object file, CPU machine code, a loadable executable, or an already running process?

Code Forms Need Their Own Readers

Bytecode, object code, and machine code are not interchangeable names for the same thing.

They are different byte-based code representations aimed at different readers.

The distinction matters because running behavior appears only when the right layer reads the representation in the right runtime context.