Hai, teman-teman! Sebelum kenalan dengan Scanner di Java, coba lihat lagi kasir Warteg Canggih kita. Delapan artikel sudah lewat, dan kasirnya sudah bisa banyak hal: menampilkan menu, merekap pesanan satu meja, menghitung diskon, sampai memecah kembalian jadi lembaran uang. Tapi ada satu hal aneh kalau dipikir-pikir.
Setiap ada pembeli baru, siapa yang mengubah isi pesanan dan uangPembeli? Kita, programmernya. Buka kode, ganti angkanya, simpan, jalankan ulang. Kebayang tidak kalau kasir warteg beneran harus begitu setiap ada yang pesan? Saatnya kasir kita mendengar langsung apa yang diketik pembeli, lewat Scanner di Java.
TL;DR: Scanner adalah class bawaan Java untuk membaca input dari keyboard. Buat dengan new Scanner(System.in) setelah import java.util.Scanner;. Pakai nextInt() untuk angka, nextLine() untuk satu baris teks utuh, dan next() untuk satu kata. Jebakan terkenal: nextLine() yang dipanggil setelah nextInt() langsung mengembalikan teks kosong, karena Enter yang tersisa belum dibuang. Kalau pengguna mengetik huruf saat diminta angka, nextInt() melempar InputMismatchException. Cegah dengan mengecek hasNextInt() dulu.
Kenalan Dulu: Apa Itu Scanner di Java?
Selama ini program kita cuma "bicara" lewat System.out, yang artinya keluaran ke layar. Pasangannya adalah System.in, yaitu masukan dari keyboard. Masalahnya, System.in menerima input dalam bentuk mentah, berupa deretan byte. Untuk mengubahnya jadi angka atau teks yang siap dipakai, kita butuh penerjemah.
Penerjemah itu adalah Scanner. Menurut dokumentasi resmi Scanner, Scanner memecah input menjadi potongan-potongan yang disebut token, yang secara bawaan dipisahkan oleh spasi atau baris baru, lalu bisa mengubah tiap token jadi tipe yang kita minta.
Scanner tidak otomatis tersedia seperti String. Dia tinggal di paket java.util, jadi harus di-import dulu di baris paling atas file, sama seperti Arrays di artikel Array di Java:
import java.util.Scanner;
public class WartegCanggih {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
// input siap dipakai
}
}
input adalah nama variabelnya. Boleh diganti apa saja, misalnya scanner atau keyboard.
Membaca Angka dengan Scanner di Java: nextInt
Untuk membaca bilangan bulat, pakai nextInt():
System.out.print("Berapa porsi? ");
int jumlah = input.nextInt();
System.out.println("Oke, " + jumlah + " porsi.");
Perhatikan pemakaian print, bukan println, untuk pertanyaannya. Dengan print, kursor tetap di baris yang sama, jadi pembeli mengetik jawabannya tepat di sebelah pertanyaan:
Berapa porsi? 2
Oke, 2 porsi.
Saat sampai di nextInt(), program berhenti dan menunggu sampai pengguna mengetik sesuatu lalu menekan Enter. Untuk angka bertipe lain, ada pasangannya: nextDouble(), nextLong(), dan nextBoolean().
Membaca Teks: nextLine dan next
Untuk teks, ada dua pilihan, dan bedanya penting:
nextLine()membaca satu baris utuh sampai Enter, termasuk spasi di dalamnya.next()hanya membaca satu token, yaitu satu "kata" sampai ketemu spasi.
Kalau pembeli mengetik Tempe orek:
String menu = input.next(); // hasilnya "Tempe"
String menu = input.nextLine(); // hasilnya "Tempe orek"
Untuk nama atau catatan yang bisa berisi spasi, pakai nextLine(). Kombinasikan dengan trim() dari artikel String supaya spasi berlebih di awal dan akhir ikut dibuang:
System.out.print("Atas nama siapa? ");
String namaPembeli = input.nextLine().trim();
Jebakan Terkenal: nextLine Terlewat Setelah nextInt
Ini jebakan yang hampir pasti dialami setiap orang yang baru belajar Scanner. Coba kode ini:
System.out.print("Berapa porsi? ");
int jumlah = input.nextInt();
System.out.print("Catatan: ");
String catatan = input.nextLine();
System.out.println("Porsi: " + jumlah + ", catatan: [" + catatan + "]");
Pembeli mengetik 2, menekan Enter, lalu... program tidak menunggu catatan sama sekali. Langsung selesai:
Berapa porsi? 2
Catatan: Porsi: 2, catatan: []
Catatannya kosong. Kenapa?
Saat pembeli mengetik 2 lalu Enter, yang masuk sebenarnya dua hal: angka 2 dan karakter baris baru dari tombol Enter. nextInt() hanya mengambil angkanya. Karakter Enter masih tertinggal di antrian. Lalu nextLine() datang, melihat ada "sisa baris" yang isinya kosong sebelum Enter itu, mengambilnya, dan langsung selesai. Menurut dokumentasi Scanner, nextLine() memang mengembalikan sisa baris saat ini, apa pun isinya.
Analoginya seperti antrian di kasir. nextInt() melayani pembelinya, tapi kertas antriannya tertinggal di meja. Pembeli berikutnya, nextLine(), mengira kertas itu miliknya, mengambilnya, lalu pergi.
Solusinya, buang sisa Enter itu dengan satu nextLine() tambahan yang hasilnya tidak disimpan:
int jumlah = input.nextInt();
input.nextLine(); // buang sisa Enter
System.out.print("Catatan: ");
String catatan = input.nextLine(); // sekarang benar-benar menunggu
Patokannya: setiap kali mau memanggil nextLine() setelah nextInt() (atau next...() lain selain nextLine), sisipkan satu nextLine() pembuang dulu.
Jebakan: Pengguna Mengetik Huruf Saat Diminta Angka
Pembeli itu manusia, dan manusia mengetik apa saja. Saat ditanya "Berapa porsi?", bisa saja dia mengetik dua. Hasilnya:
Berapa porsi? dua
Exception in thread "main" java.util.InputMismatchException
Program mati di tempat. Dokumentasi InputMismatchException menjelaskan bahwa exception ini dilempar saat token yang dibaca tidak cocok dengan tipe yang diminta.
Cara rapi menangani exception, yaitu try dan catch, baru dibahas di Tahap 2. Untuk sekarang, kita cegah saja supaya exception-nya tidak pernah terjadi. Scanner punya hasNextInt(), yang mengecek apakah token berikutnya bisa dibaca sebagai int, tanpa benar-benar mengambilnya. Gabungkan dengan while dan bungkus dalam method, seperti yang kita pelajari di artikel Method di Java:
static int bacaAngka(Scanner input) {
while (!input.hasNextInt()) {
String salah = input.next(); // buang input yang bukan angka
System.out.print("\"" + salah + "\" bukan angka, coba lagi: ");
}
return input.nextInt();
}
Selama token berikutnya bukan angka, buang token itu dengan next(), lalu minta lagi. Begitu yang masuk angka, perulangan berhenti dan angkanya dikembalikan. Baris input.next() itu wajib: tanpa itu, dua tetap tertinggal di antrian, hasNextInt() terus bernilai false, dan kita mendapat infinite loop.
Pemakaiannya cukup int jumlah = bacaAngka(input);, dan kasir tidak akan mati gara-gara salah ketik:
Berapa porsi? dua
"dua" bukan angka, coba lagi: 1
Menu Interaktif dengan do-while
Di artikel Perulangan di Java, kita sudah menyebut bahwa do-while cocok untuk menu yang harus tampil minimal sekali. Sekarang saatnya dipakai. Kasir terus menanyakan nomor menu sampai pembeli mengetik 0:
int pilihan;
do {
System.out.print("Nomor menu (0 = selesai): ");
pilihan = bacaAngka(input);
if (pilihan == 0) {
continue;
}
// proses pesanan untuk menu nomor pilihan
} while (pilihan != 0);
Pertanyaannya pasti muncul minimal sekali, lalu diulang selama pilihannya bukan 0. Di dalam do-while, continue langsung melompat ke pengecekan while (pilihan != 0). Jadi saat pilihan 0, perulangan langsung selesai tanpa memproses apa-apa. Kalau pilihannya nomor yang tidak ada, continue membuat pertanyaan diulang.
Variabel pilihan dibuat sebelum do, bukan di dalamnya, karena dipakai juga di syarat while yang ada di luar kurung kurawal.
Menutup Scanner
Setelah selesai dipakai, Scanner sebaiknya ditutup dengan input.close(). Tapi ada satu hal yang perlu diketahui: menurut dokumentasi Scanner, menutup Scanner juga ikut menutup sumber inputnya, yang dalam kasus ini adalah System.in. Setelah itu, keyboard tidak bisa dibaca lagi oleh Scanner mana pun di program yang sama.
Jadi aturannya sederhana: buat satu Scanner di awal program, pakai bersama untuk semua input, dan tutup sekali di akhir.
Kasir Warteg Versi 9: Pembeli Mengetik Sendiri
Sekarang semua digabung. Kasir menanyakan nama pembeli, menerima pesanan berulang lewat do-while, meminta catatan untuk dapur (lengkap dengan pembuangan sisa Enter), mencetak struk, lalu meminta uang pembeli sampai jumlahnya cukup.
import java.util.Scanner;
public class WartegCanggih {
public static void main(String[] args) {
final String NAMA_WARTEG = "Warteg Canggih";
String[] namaMenu = {"Nasi putih", "Tempe orek", "Es teh", "Telur balado", "Sayur asem"};
int[] hargaMenu = {5000, 4000, 3000, 6000, 4000};
Scanner input = new Scanner(System.in);
System.out.println("Selamat datang di " + NAMA_WARTEG + "!");
System.out.print("Atas nama siapa? ");
String namaPembeli = input.nextLine().trim();
tampilkanMenu(namaMenu, hargaMenu);
int[] porsi = new int[namaMenu.length];
int pilihan;
do {
System.out.print("Nomor menu (0 = selesai): ");
pilihan = bacaAngka(input);
if (pilihan == 0) {
continue; // langsung ke pengecekan while, lalu keluar
}
int index = pilihan - 1;
if (index < 0 || index >= namaMenu.length) {
System.out.println("Menu nomor " + pilihan + " tidak ada.");
continue;
}
System.out.print("Berapa porsi? ");
int jumlah = bacaAngka(input);
if (jumlah <= 0) {
System.out.println("Jumlah porsi minimal 1.");
continue;
}
porsi[index] += jumlah;
System.out.println("Dicatat: " + namaMenu[index] + " x" + jumlah);
} while (pilihan != 0);
input.nextLine(); // buang sisa Enter setelah angka terakhir
System.out.print("Catatan untuk dapur (boleh kosong): ");
String catatan = input.nextLine().trim();
int subtotal = hitungSubtotal(hargaMenu, porsi);
if (subtotal == 0) {
System.out.println("Tidak ada pesanan. Sampai jumpa, " + namaPembeli + "!");
input.close();
return;
}
int diskon = hitungDiskon(subtotal);
int total = subtotal - diskon;
System.out.println();
System.out.println("Pesanan atas nama " + namaPembeli);
cetakRincian(namaMenu, hargaMenu, porsi);
cetakGaris(28);
cetakBaris("Subtotal", subtotal);
cetakBaris("Diskon", diskon);
cetakBaris("TOTAL", total);
if (!catatan.isEmpty()) {
System.out.println("Catatan: " + catatan);
}
System.out.println();
System.out.print("Uang pembeli: ");
int uangPembeli = bacaAngka(input);
while (uangPembeli < total) {
System.out.print("Uang kurang Rp" + (total - uangPembeli) + ". Masukkan ulang: ");
uangPembeli = bacaAngka(input);
}
cetakKembalian(uangPembeli - total);
input.close();
}
static int bacaAngka(Scanner input) {
while (!input.hasNextInt()) {
String salah = input.next(); // buang input yang bukan angka
System.out.print("\"" + salah + "\" bukan angka, coba lagi: ");
}
return input.nextInt();
}
static void tampilkanMenu(String[] namaMenu, int[] hargaMenu) {
System.out.println("Daftar menu:");
for (int i = 0; i < namaMenu.length; i++) {
System.out.println((i + 1) + ". " + namaMenu[i] + " (Rp" + hargaMenu[i] + ")");
}
}
static void cetakRincian(String[] namaMenu, int[] hargaMenu, int[] porsi) {
for (int i = 0; i < namaMenu.length; i++) {
if (porsi[i] > 0) {
int hargaBaris = hargaMenu[i] * porsi[i];
System.out.println(String.format("%-14s%3s%11s", namaMenu[i], "x" + porsi[i], "Rp" + hargaBaris));
}
}
}
static int hitungSubtotal(int[] hargaMenu, int[] porsi) {
int subtotal = 0;
for (int i = 0; i < hargaMenu.length; i++) {
subtotal += hargaMenu[i] * porsi[i];
}
return subtotal;
}
static int hitungDiskon(int subtotal) {
if (subtotal >= 20000) {
return 2000;
}
if (subtotal >= 10000) {
return 1000;
}
return 0;
}
static void cetakGaris(int panjang) {
System.out.println("-".repeat(panjang));
}
static void cetakBaris(String label, int nominal) {
System.out.println(String.format("%-17s%11s", label, "Rp" + nominal));
}
static void cetakKembalian(int sisa) {
System.out.println("Kembalian: Rp" + sisa);
int[] pecahan = {10000, 5000, 2000, 1000};
for (int lembar : pecahan) {
while (sisa >= lembar) {
System.out.println(" Rp" + lembar);
sisa -= lembar;
}
}
}
}
Contoh satu sesi, dengan ketikan pembeli ada di belakang tiap pertanyaan:
Selamat datang di Warteg Canggih!
Atas nama siapa? Budi
Daftar menu:
1. Nasi putih (Rp5000)
2. Tempe orek (Rp4000)
3. Es teh (Rp3000)
4. Telur balado (Rp6000)
5. Sayur asem (Rp4000)
Nomor menu (0 = selesai): 2
Berapa porsi? 2
Dicatat: Tempe orek x2
Nomor menu (0 = selesai): 7
Menu nomor 7 tidak ada.
Nomor menu (0 = selesai): 1
Berapa porsi? dua
"dua" bukan angka, coba lagi: 1
Dicatat: Nasi putih x1
Nomor menu (0 = selesai): 4
Berapa porsi? 1
Dicatat: Telur balado x1
Nomor menu (0 = selesai): 0
Catatan untuk dapur (boleh kosong): sambalnya dipisah
Pesanan atas nama Budi
Nasi putih x1 Rp5000
Tempe orek x2 Rp8000
Telur balado x1 Rp6000
----------------------------
Subtotal Rp19000
Diskon Rp1000
TOTAL Rp18000
Catatan: sambalnya dipisah
Uang pembeli: 15000
Uang kurang Rp3000. Masukkan ulang: 30000
Kembalian: Rp12000
Rp10000
Rp2000
Catatan untuk dapur boleh dikosongkan. Method isEmpty() mengecek apakah sebuah String tidak berisi karakter sama sekali, jadi baris Catatan: hanya dicetak kalau pembeli benar-benar menulis sesuatu.
Ada tiga perilaku baru yang bisa dicoba: nomor menu yang tidak ada ditolak tanpa mematikan program, ketikan huruf diminta ulang, dan uang yang kurang ditagih lagi lewat while.
Program ini harus dijalankan di terminal yang bisa diketik, misalnya Command Prompt, PowerShell, atau terminal bawaan editor. Langkah menjalankannya sama seperti di Mengenal Java dan Menjalankan Program Java Pertama.
Error Umum Pemula
1. Lupa import.
error: cannot find symbol
symbol: class Scanner
Tambahkan import java.util.Scanner; di baris paling atas file, sebelum public class.
2. nextLine() langsung kosong. Penyebabnya sisa Enter dari nextInt(). Sisipkan input.nextLine(); pembuang sebelum membaca teks.
3. InputMismatchException. Pengguna mengetik bukan angka saat nextInt() dipanggil. Cek dulu dengan hasNextInt(), seperti di method bacaAngka.
4. Infinite loop di validasi angka. Lupa input.next() di dalam while (!input.hasNextInt()), sehingga input yang salah tidak pernah dibuang.
5. Membuat Scanner baru di dalam perulangan atau menutupnya di tengah jalan. Setelah satu Scanner ditutup, System.in ikut tertutup, dan Scanner berikutnya tidak bisa membaca keyboard. Cukup satu Scanner untuk satu program.
Penutup
Pelajaran terbesar dari artikel ini sebenarnya bukan soal Scanner, tapi soal cara berpikir: begitu program menerima input dari manusia, kita harus siap dengan semua kemungkinan ketikan. Nomor yang tidak ada, huruf di tempat angka, porsi nol, uang kurang. Separuh kode kasir versi 9 adalah kode untuk menjaga dari kemungkinan-kemungkinan itu.
Coba jalankan kasirnya, lalu sengaja jadi pembeli yang menyebalkan. Ketik angka negatif, ketik -0, ketik 2 2 (dua angka dalam satu baris), atau langsung ketik 0 tanpa memesan apa pun. Catat perilaku mana yang menurutmu belum pas, karena itu akan jadi bahan perbaikan di artikel berikutnya.
Satu lagi untuk dipikirkan: kalau pembeli salah pesan, bagaimana cara membatalkannya? Kasir versi 9 belum bisa melakukannya. Coba pikirkan dulu caranya, karena jawabannya akan kita bahas di Tahap 2 lewat artikel Stack dan Queue.
Di artikel berikutnya, Program Kasir Warteg: Menggabungkan Semua yang Sudah Dipelajari, semua potongan dari artikel 1 sampai 9 kita rakit ulang jadi satu program kasir yang utuh, sebagai penutup Tahap 1.
Kalau mau lihat contoh program lama yang juga memakai Scanner, ada di Program Penghitung Waktu (Billing) menggunakan Java.
Daftar semua artikel seri ini ada di label Warteg Canggih Series. Ketikan paling aneh apa yang berhasil bikin kasirmu bingung? Tulis di kolom komentar.
Source code lengkap artikel ini bisa dilihat di GitHub: 09-membaca-input-scanner-java
FAQ
Apa itu Scanner di Java?
Scanner adalah class bawaan Java di paket java.util untuk membaca input, misalnya dari keyboard lewat System.in. Scanner memecah input jadi token dan bisa mengubahnya langsung jadi int, double, String, dan tipe lain.
Kenapa nextLine tidak menunggu input setelah nextInt?
nextInt() hanya mengambil angka dan meninggalkan karakter Enter di antrian input. nextLine() berikutnya langsung membaca sisa baris yang kosong itu. Solusinya, panggil satu nextLine() tambahan untuk membuang sisa Enter sebelum membaca teks.
Apa bedanya next dan nextLine?
next() membaca satu token, yaitu satu kata sampai ketemu spasi. nextLine() membaca satu baris utuh sampai Enter, termasuk spasi di dalamnya, sehingga cocok untuk nama atau catatan.
Bagaimana cara mencegah InputMismatchException?
Cek dulu dengan hasNextInt() sebelum memanggil nextInt(). Kalau hasilnya false, buang token yang salah dengan next(), lalu minta pengguna mengetik ulang di dalam perulangan.
Apakah Scanner harus ditutup?
Sebaiknya ditutup dengan close() setelah selesai dipakai. Karena menutup Scanner juga menutup System.in, tutup sekali saja di akhir program dan pakai satu Scanner untuk semua input.
Referensi
- Class Scanner, Java SE 21 API, diakses 10 Oktober 2026
- Class InputMismatchException, Java SE 21 API, diakses 10 Oktober 2026
- Scanning, The Java Tutorials (Oracle), diakses 10 Oktober 2026

Posting Komentar untuk "Membaca Input dari Pengguna dengan Scanner"