Java Dasar: Variabel, Tipe Data, Operator & Alur Kontrol
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:
| Istilah | Kepanjangan | Fungsinya |
|---|---|---|
| JVM | Java Virtual Machine | Menjalankan bytecode. Bagian yang membuat Java "portable" |
| JRE | Java Runtime Environment | JVM + library standar. Cukup untuk menjalankan program Java |
| JDK | Java Development Kit | JRE + 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):
| Aturan | Benar | Salah |
|---|---|---|
| Huruf pertama huruf kecil, kata berikutnya kapital | totalHarga, namaLengkap | total_harga, NamaLengkap |
| Tidak boleh diawali angka | pesanan1 | 1pesanan |
| Tidak boleh memakai keyword Java | id | int, class, static |
| Deskriptif, bukan singkatan | hargaPerItem | h |
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:
| Tipe | Ukuran | Rentang Nilai | Contoh |
|---|---|---|---|
byte | 8 bit | -128 s/d 127 | byte suhu = 36; |
short | 16 bit | -32.768 s/d 32.767 | short jarak = 1500; |
int | 32 bit | ±2,1 miliar | int jumlah = 1_000_000; |
long | 64 bit | sangat besar | long id = 987_654_321L; |
float | 32 bit | desimal (presisi rendah) | float harga = 9.99f; |
double | 64 bit | desimal (presisi lebih baik) | double total = 120.50; |
boolean | 1 bit | true / false | boolean aktif = true; |
char | 16 bit | satu karakter | char 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 (\):
| Escape | Artinya |
|---|---|
\n | baris baru |
\t | tab |
\\ | 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
| Operator | Fungsi | Contoh |
|---|---|---|
+ - * / % | tambah, kurang, kali, bagi, sisa bagi | 7 % 3 → 1 |
+= -= *= /= %= | hitung lalu tugaskan kembali | x += 5 sama dengan x = x + 5 |
++ -- | naik/turun satu | count++ |
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
| Operator | Fungsi | Contoh |
|---|---|---|
== != | sama dengan / tidak sama | role == "ADMIN" |
> < >= <= | lebih besar / lebih kecil | saldo >= 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 bernilaifalsemeski 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.
| Prioritas | Operator |
|---|---|
| 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?
| Kebutuhan | Pilih | Alasannya |
|---|---|---|
| Percabangan sederhana | if/else | Paling jelas untuk 2-3 kondisi |
| Satu nilai, banyak kemungkinan | switch | Lebih rapi daripada rantai else if |
| Iterasi index tertentu | for | Kontrol lengkap atas index |
| Ambil semua elemen | for-each | Paling aman, tidak bisa salah index |
| Jumlah iterasi tak pasti | while | Berhenti berdasarkan kondisi |
| Harus jalan minimal sekali | do-while | Sering 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?
- Collections (
List,Map,Set) tidak bisa menyimpan tipe primitif — hanya objek. - Nilai
nulltidak 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
Integeryang berisinull, akan munculNullPointerException— ini salah satu musuh utama backend engineer. Selalu periksanullsebelum 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.
Variabeladalah kotak bernama bertipe; namai dengan camelCase dan gunakanfinaluntuk 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
Stringdengan.equals(), bukan==. Kenali escape characters seperti\ndan\". - Kuasai operator aritmatika, perbandingan, logika, unary, dan ternary; pakai tanda kurung bila ragu dengan precedence.
- Pilih alur kontrol yang tepat:
if/elseuntuk percabangan,switchuntuk banyak kemungkinan,for/for-each/while/do-whileuntuk 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 mendukungnull— waspadaiNullPointerExceptionsaat unboxing.- Gunakan
StringBuilderuntuk menggabungkan banyak String agar efisien.
Lanjut membaca
- Lesson: Language Basics (Oracle) — peta lengkap sintaks dasar Java.
- Primitive Data Types (Oracle) — detail 8 tipe primitif dan default value-nya.
- Operators (Oracle) — semua operator beserta precedence.
- Control Flow Statements (Oracle) —
if,switch, dan semua jenis perulangan.
Selanjutnya, lanjut ke Konsep OOP di Java untuk memahami class, object, dan inheritance — inti dari penulisan kode backend yang rapi.