Java Dasar: Variabel, Tipe Data, Operator & Alur Kontrol

12 min readFundamental
JavaDasarBackend

Bahasa Java adalah salah satu bahasa paling banyak dipakai untuk membangun backend — dari aplikasi perbankan, marketplace, sampai layanan streaming. Artikel ini mengajak Anda mempelajari fondasinya: variabel dan tipe data, operator, alur kontrol (if/switch/perulangan), array, serta cara membaca input. Semua contoh kode bisa langsung Anda salin dan jalankan, jadi siapkan Java di komputer Anda dan mulai praktik di sela-sela membaca.

Apa itu Java, JDK, JRE, dan JVM?

Java adalah bahasa pemrograman berorientasi objek yang dikompilasi menjadi bytecode, lalu dijalankan di atas JVM (Java Virtual Machine) — "mesin virtual" yang membuat program Java bisa jalan di mana saja (Windows, Linux, macOS) tanpa perlu dikompilasi ulang. Inilah slogan terkenalnya: write once, run anywhere.

Saat belajar Java, Anda akan sering mendengar tiga singkatan:

IstilahKepanjanganFungsinya
JVMJava Virtual MachineMenjalankan bytecode. Bagian yang membuat Java "portable"
JREJava Runtime EnvironmentJVM + library standar. Cukup untuk menjalankan program Java
JDKJava Development KitJRE + compiler (javac) + tool lain. Dibutuhkan untuk menulis dan mengompilasi kode

Konsep kunci: sebagai backend engineer, Anda butuh JDK untuk menulis kode. Yang dipakai hanya JRE cukup untuk menjalankan aplikasi Java yang sudah jadi di server.

Kenapa Java masih jadi pilihan utama untuk backend?

  • Mature ecosystem — framework seperti Spring Boot sudah teruji untuk aplikasi skala besar.
  • Kinerja stabil — JVM melakukan just-in-time compilation, sehingga performanya mendekati bahasa native.
  • Dukungan concurrency bawaan — cocok untuk server yang melayani ribuan request bersamaan.
  • Komunitas dan lowongan kerja besar — banyak perusahaan backend Indonesia memakai Java/Spring.

Variabel: Tempat Menyimpan Nilai

Variabel adalah "kotak bernama" di memori untuk menyimpan nilai. Di Java, setiap variabel wajib dideklarasikan dengan tipe data sebelum dipakai.

int umur = 25;              // deklarasi + inisialisasi sekaligus
String nama;                // deklarasi dulu...
nama = "Hendro";            // ...inisialisasi kemudian

double saldo;               // error! variabel belum diberi nilai, tak bisa dipakai

Aturan penamaan variabel di Java (camelCase):

AturanBenarSalah
Huruf pertama huruf kecil, kata berikutnya kapitaltotalHarga, namaLengkaptotal_harga, NamaLengkap
Tidak boleh diawali angkapesanan11pesanan
Tidak boleh memakai keyword Javaidint, class, static
Deskriptif, bukan singkatanhargaPerItemh

Untuk nilai yang tidak boleh berubah, gunakan kata kunci final — nilainya menjadi konstanta.

final double PI = 3.14159;
final int MAX_RETRY = 3;

MAX_RETRY = 5;   // error! tidak bisa diubah setelah diinisialisasi

Konsep kunci: kebiasaan baik di backend adalah menandai nilai yang memang tetap dengan final. Ini membuat kode lebih mudah dibaca dan mencegah perubahan tak sengaja.

Tipe Data Primitif dan Reference

Java punya dua keluarga besar tipe data: primitif dan reference.

Tipe Data Primitif

Tipe primitif menyimpan nilai langsung di variabel. Ada 8 jenis:

TipeUkuranRentang NilaiContoh
byte8 bit-128 s/d 127byte suhu = 36;
short16 bit-32.768 s/d 32.767short jarak = 1500;
int32 bit±2,1 miliarint jumlah = 1_000_000;
long64 bitsangat besarlong id = 987_654_321L;
float32 bitdesimal (presisi rendah)float harga = 9.99f;
double64 bitdesimal (presisi lebih baik)double total = 120.50;
boolean1 bittrue / falseboolean aktif = true;
char16 bitsatu karakterchar inisial = 'A';

Perhatikan penggunaan L di 987_654_321L untuk long dan f di 9.99f untuk float — ini penanda literal agar Java tahu tipenya. Tanda _ pada angka (1_000_000) hanya pemisah visual agar mudah dibaca; nilainya tetap 1000000.

Tipe Data Reference

Tipe reference menyimpan alamat ke objek di memori, bukan nilainya. Contoh paling umum: String, array, dan objek buatan Anda sendiri.

String email = "hendro@mail.com";   // String adalah objek, bukan primitif
int[] angka = {1, 2, 3};            // array

Primitif vs Reference: Pass-by-Value

Perbedaan paling membingungkan di awal — tapi wajib dipahami. Java selalu melempar nilai (pass-by-value). Untuk tipe primitif, yang disalin adalah nilainya. Untuk tipe reference, yang disalin adalah alamatnya (kedua variabel menunjuk objek yang sama).

// Kasus 1: primitif — nilai disalin
int a = 10;
int b = a;
b = 99;
System.out.println(a);   // 10, nilai a tidak berubah
// Kasus 2: reference — alamat disalin, objeknya sama
String[] x = {"a", "b"};
String[] y = x;
y[0] = "Z";
System.out.println(x[0]);   // "Z", karena x dan y menunjuk objek array yang sama

Konsep kunci: "primitif = salinan nilai, reference = salinan alamat". Salah memahami ini sering menjadi sumber bug yang sulit dilacak di backend.

String: Literal dan Escape Characters

String adalah kumpulan karakter. Ada dua cara menulis literal String — langsung atau dengan operator new:

String s1 = "hello";              // literal, disimpan di string pool
String s2 = new String("hello");  // membuat objek baru di heap (umumnya dihindari)

Untuk escape characters — karakter khusus yang butuh tanda baca aneh — gunakan garis miring terbalik (\):

EscapeArtinya
\nbaris baru
\ttab
\\satu karakter backslash (\)
\"tanda kutip ganda
\'tanda kutip tunggal
String alamat = "Jl. Merdeka No. 12\\Kav 3";
String pesan = "Kata \"selamat\" ditulis dalam tanda kutip.";

Operator

Operator adalah simbol yang memproses nilai. Berikut kelompoknya.

Operator Aritmatika dan Penugasan

OperatorFungsiContoh
+ - * / %tambah, kurang, kali, bagi, sisa bagi7 % 31
+= -= *= /= %=hitung lalu tugaskan kembalix += 5 sama dengan x = x + 5
++ --naik/turun satucount++

Waspada pembagian antar int — hasilnya dipotong, bukan dibulatkan:

int a = 7, b = 2;
System.out.println(a / b);   // 3, bukan 3.5 (hasil dibulatkan ke bawah)
System.out.println(a % b);   // 1, sisa bagi

Operator Perbandingan dan Logika

OperatorFungsiContoh
== !=sama dengan / tidak samarole == "ADMIN"
> < >= <=lebih besar / lebih kecilsaldo >= 10000
&&DAN (keduanya harus true)aktif && role.equals("ADMIN")
||ATAU (salah satu true sudah cukup)a == 1 || a == 2
!NEGASI (membalik nilai boolean)!aktif

Perangkap klasik: untuk membandingkan String, jangan pakai == (membandingkan alamat), tapi pakai method .equals(). role == "ADMIN" bisa bernilai false meski isinya sama!

Operator Ternary

Ternary operator adalah if-else versi ringkas dalam satu baris dengan bentuk kondisi ? nilai1 : nilai2.

int umur = 17;
String kategori = umur >= 18 ? "dewasa" : "anak-anak";
System.out.println(kategori);   // anak-anak

Precedence Operator

Bila beberapa operator dipakai sekaligus, Java mengikuti urutan prioritas (tinggi ke rendah). Saat ragu, pakai tanda kurung () — lebih aman dan lebih mudah dibaca.

PrioritasOperator
1 (tertinggi)() tanda kurung, []
2++ -- ! (unary)
3* / %
4+ -
5< <= > >=
6== !=
7&&
8||
9 (terendah)= += -= (penugasan)
boolean hasil = 2 + 3 * 4 == 14 && !false;   // true — 3*4=12, 2+12=14, 14==14, !false → true && true

Alur Kontrol

Alur kontrol menentukan jalan eksekusi program — memutuskan dan mengulang. Mari bahas satu per satu.

Percabangan: if, else if, else

int skor = 85;
if (skor >= 90) {
    System.out.println("A");
} else if (skor >= 80) {
    System.out.println("B");
} else {
    System.out.println("C");
}

Contoh realistis di backend — validasi input sederhana:

String email = "hendro@mail.com";
if (email == null || email.isBlank()) {
    System.out.println("ERROR: email wajib diisi");
} else if (!email.contains("@")) {
    System.out.println("ERROR: format email tidak valid");
} else {
    System.out.println("OK: email valid");
}

Percabangan: switch

switch cocok saat membandingkan satu nilai dengan banyak kemungkinan. Sejak Java 14, ada switch expression yang lebih ringkas dan tidak perlu break:

String status = "ACTIVE";
String deskripsi = switch (status) {
    case "ACTIVE"  -> "Akun aktif";
    case "SUSPEND" -> "Akun dibekukan";
    case "BANNED"  -> "Akun diblokir";
    default        -> "Status tidak dikenal";
};
System.out.println(deskripsi);   // Akun aktif

Perulangan: for, for-each, while, do-while

// for klasik — tahu persis berapa kali iterasi
for (int i = 0; i < 5; i++) {
    System.out.println("iterasi ke-" + i);
}

// while — dijalankan selama kondisi benar (cek dulu)
int retry = 0;
while (retry < 3 && koneksiGagal()) {
    retry++;
}
// do-while — dijalankan minimal sekali (cek belakangan)
int pilihan;
do {
    pilihan = bacaInput();
} while (pilihan != 0);

Kata kunci break menghentikan perulangan sepenuhnya; continue melompati iterasi saat ini.

for (int i = 1; i <= 10; i++) {
    if (i % 2 == 0) continue;   // lewati angka genap
    if (i == 9) break;          // berhenti di 9
    System.out.print(i + " ");  // 1 3 5 7
}

Kapan Memakai yang Mana?

KebutuhanPilihAlasannya
Percabangan sederhanaif/elsePaling jelas untuk 2-3 kondisi
Satu nilai, banyak kemungkinanswitchLebih rapi daripada rantai else if
Iterasi index tertentuforKontrol lengkap atas index
Ambil semua elemenfor-eachPaling aman, tidak bisa salah index
Jumlah iterasi tak pastiwhileBerhenti berdasarkan kondisi
Harus jalan minimal sekalido-whileSering dipakai untuk menu input

Array

Array adalah kumpulan elemen bertipe sama dengan ukuran tetap. Index dimulai dari 0.

// deklarasi + inisialisasi
int[] harga = {15000, 25000, 50000};
String[] nama = new String[3];     // array kosong ukuran 3

// akses index
System.out.println(harga[0]);      // 15000
harga[1] = 26000;                  // ubah elemen

// iterasi
for (int h : harga) {
    System.out.println("Harga: " + h);
}

Mengakses index di luar batas memicu ArrayIndexOutOfBoundsException — salah satu error paling sering di awal belajar.

Array Multi-Dimensi

Array di dalam array — sering dipakai untuk matriks atau papan permainan.

int[][] matriks = {
    {1, 2},
    {3, 4}
};
System.out.println(matriks[0][1]);   // 2 (baris 0, kolom 1)

Class Wrapper: Primitive dalam Bentuk Objek

Tiap tipe primitif punya class wrapper — versi objeknya: Integer, Long, Double, Boolean, Character, dan seterusnya. Mengapa dibutuhkan?

  1. Collections (List, Map, Set) tidak bisa menyimpan tipe primitif — hanya objek.
  2. Nilai null tidak bisa disimpan di primitif, tapi bisa di objek.
import java.util.ArrayList;
import java.util.List;

List<Integer> ids = new ArrayList<>();   // List of int tidak bisa, harus Integer
ids.add(42);
ids.add(null);   // boleh, karena Integer adalah objek

Integer a = 10;      // autoboxing: int → Integer otomatis
int b = a + 5;       // unboxing: Integer → int otomatis

Konsep kunci: Java melakukan autoboxing/unboxing otomatis antara primitif dan wrapper. Namun saat primitif di-unboxing dari Integer yang berisi null, akan muncul NullPointerException — ini salah satu musuh utama backend engineer. Selalu periksa null sebelum memproses.

StringBuilder: Menggabungkan String dengan Efisien

String di Java bersifat immutable — sekali dibuat tidak bisa diubah. Maka + di dalam perulangan membuat objek baru setiap iterasi, boros memori.

// Lambat & boros: membuat banyak objek String baru
String hasil = "";
for (int i = 0; i < 10000; i++) {
    hasil += "baris-" + i + "\n";
}

// Cepat: StringBuilder mengubah isinya, bukan membuat objek baru
StringBuilder sb = new StringBuilder();
for (int i = 0; i < 10000; i++) {
    sb.append("baris-").append(i).append("\n");
}
String hasil = sb.toString();

Untuk 10.000 iterasi, versi + bisa berkali-kali lipat lebih lambat. Di kode backend yang memproses log besar atau membangun payload besar, StringBuilder adalah pilihan yang benar.

Input dari Pengguna: Scanner

Untuk program sederhana di terminal, gunakan Scanner dari paket java.util.

import java.util.Scanner;

Scanner scanner = new Scanner(System.in);
System.out.print("Masukkan nama: ");
String nama = scanner.nextLine();
System.out.print("Masukkan umur: ");
int umur = scanner.nextInt();
System.out.println("Halo " + nama + ", umur Anda " + umur);
scanner.close();

Untuk API backend, input umumnya datang sebagai JSON yang diparsing oleh framework (misal Spring). Namun memahami Scanner melatih intuisi membaca data mentah — keterampilan yang berguna saat menulis script utilitas atau kode batch processing.

Ringkasan

  • Java dikompilasi menjadi bytecode dan dijalankan di JVM; JDK untuk menulis kode, JRE untuk menjalankannya. Java dipilih untuk backend karena ekosistemnya matang, kinerja stabil, dan dukungan concurrency-nya kuat.
  • Variabel adalah kotak bernama bertipe; namai dengan camelCase dan gunakan final untuk nilai tetap.
  • Ada 8 tipe primitif (byte, short, int, long, float, double, boolean, char) dan tipe reference (String, array, objek). Java selalu pass-by-value — primitif menyalin nilai, reference menyalin alamat.
  • Bandingkan String dengan .equals(), bukan ==. Kenali escape characters seperti \n dan \".
  • Kuasai operator aritmatika, perbandingan, logika, unary, dan ternary; pakai tanda kurung bila ragu dengan precedence.
  • Pilih alur kontrol yang tepat: if/else untuk percabangan, switch untuk banyak kemungkinan, for/for-each/while/do-while untuk perulangan sesuai kebutuhan.
  • Array berindex 0 dan berukuran tetap; hati-hati dengan out-of-bounds.
  • Integer, Double, dll. adalah class wrapper yang dibutuhkan collections dan mendukung null — waspadai NullPointerException saat unboxing.
  • Gunakan StringBuilder untuk menggabungkan banyak String agar efisien.

Lanjut membaca

Selanjutnya, lanjut ke Konsep OOP di Java untuk memahami class, object, dan inheritance — inti dari penulisan kode backend yang rapi.

← Back to technical articles