+6

Java cơ bản - phần 1

A. Introduction

1. Java

Java là ngôn ngữ lập trình cấp cao (high level) và là một nền tảng (platform) để chạy các chương trình viết bằng Java.

Java có thể tạo nhiều loại ứng dụng khác nhau:

  • Standalone application: ứng dụng độc lập
  • Web application: chạy trên server, tạo web động
  • Enterprise application: ứng dụng dành cho doanh nghiệp, bank,... bảo mật, chịu tải cao
  • Mobile application

Có khoảng 3 tỉ thiết bị chạy Java platform, chứng tỏ Java rất phổ biến hiện nay.

2. History

James Gosling và các cộng sự đã tạo ra ngôn ngữ Java, ban đầu có tên là Greentalk, rồi đổi thành Oak (cây sồi). Lúc đầu Java chỉ dùng cho các thiết bị điện tử và nhúng. Đến năm 1995 đổi tên thành Java.

Java trải qua nhiều version khác nhau, bản mới nhất là SE 14.

Java hiện đang được sở hữu bởi Sun Microsystem (thuộc Orable).

3. Editions

Có 4 phiên bản chính, dành cho các mục đích khác nhau:

  • Java Card: dành cho smartcard như ATM, SIM,...
  • Java Micro Edition (ME): phiên bản nhỏ gọn cho mobile, nhúng
  • Java Standard Edition (SE): phiên bản tiêu chuẩn, cốt lõi của Java
  • Java Enterprise Edition (EE): phiên bản doanh nghiệp, hệ thống lớn

4. Features

Một số đặc điểm, tính năng quan trọng và vượt trội của Java có thể kể đến như sau.

Platform independent

Độc lập nền tảng là đặc điểm quan trọng nhất của Java. Java biên dịch source code thành bytecode độc lập nền tảng, chạy được bất kì phần cứng, HĐH nào hỗ trợ Java platform.

Write once, run anywhere - Tiêu chí của Java

Simple

Java là ngôn ngữ đơn giản, cú pháp dễ học tương tự C++ nhưng bỏ đi một số tính năng không cần thiết, rườm rà (pointer, operator overloading,...)

Bên cạnh đó, Java còn có GC giúp tự động dọn dẹp, quản lý bộ nhớ mà không cần quản lý thủ công.

Object oriented

Java là ngôn ngữ thuần hướng đối tượng (OOP).

Multi threaded

Chương trình Java có thể có nhiều thread, nên tốc độ và hiệu suất sẽ tốt hơn.

Secure

Java khá an toàn, hạn chế tối đa các vấn đề bảo mật tiềm ẩn. Java bỏ sử dụng pointer, ép kiểu chặt chẽ và cơ chế xác minh code nghiêm ngặt.

Ngoài ra, do chương trình Java chạy trong máy ảo JVM nên lỗi phát sinh dễ dàng kiểm soát, không ảnh hưởng tới hệ thống.

Robust

Java mạnh mẽ ở chỗ quản lý bộ nhớ tự động, có cơ chế xử lý ngoại lệ và kiểm tra lỗi nghiêm ngặt.

Portable

Bytecode của java có thể mang đi nhiều nền tảng khác nhau mà vẫn hoạt động bình thường, do đó Java có tính khả chuyển (portable).

B. Java concepts

1. Components

Java platform

Platform (nền tảng) là một loại phần cứng hoặc phần mềm có thể thực hiện chức năng chạy chương trình.

Như vậy, java platform là nền tảng cho phép chạy các chương trình java trên nó. Java platform gồm compiler, các thư viện và nhiều tools khác hỗ trợ việc chạy chương trình.

Java Virtual Machine

JWM là chương trình chuẩn bị môi trường thực thi cho ứng dụng Java. Có thể xem nó như một máy ảo (trừu tượng) để chương trình chạy bên trong nó.

JWM có 4 chức năng:

  • Tải bytecode từ file .class lên bộ nhớ (class loader)
  • Xác minh bytecode hợp lệ (verifier)
  • Thông dịch bytecode thành mã máy (interpreter) và thực thi
  • Cung cấp môi trường thực thi

Java Runtime Environment

JRE gồm JVM, các thư viện chạy và các chương trình hỗ trợ chạy ứng dụng java. Có thể so sánh JRE với .NET framework.

JRE dành cho user muốn chạy các app viết bằng java, nếu không có thì không chạy được.

Java Development Kit

JDK bao gồm JRE và các công cụ khác để hỗ trợ lập trình java (compiler, interpreter, docs,...). Khác với JRE là dành cho user, JDK dành cho lập trình viên, để viết ra các chương trình java.

Garbage Collection

GC là một thành phần của JVM, có tác dụng kiểm soát và thu gom các vùng nhớ không dùng nữa (không còn được tham chiếu đến) để trả lại cho HĐH, giúp tiết kiệm bộ nhớ,

2. IDE

Có khá nhiều IDE hỗ trợ lập trình java, nhưng mình khuyến khích sử dụng Eclipse hoặc IntelliJ IDEA để code. NetBean khá ổn nhưng mình không thích giao diện của nó, ít ra Eclipse còn đẹp hơn.

3. Build commands

Tuy mọi IDE đều hỗ trợ build và chạy chương trình java, bạn cũng nên biết cách biên dịch thủ công bằng command line.

javac Test.java

Biên dịch file Test.java thành bytecode Test.class.

java Test

Thực thi bytecode trong file Test.class và chạy chương trình. Lưu ý không cần thêm đuôi .class vào tên file.

Chương trình javac có trong JDK (cho lập trình viên) và java có trong JRE và cả JDK (vì JDK chứa JRE).

4. Build tools

Trong dự án java lớn thì có thể sử dụng nhiều thư viện, nhiều framework khác để hỗ trợ. Có những thư viện của java và cả những thư viện bên ngoài. Do đó, cần có các công cụ hỗ trợ build và quản lý các thư viện đó (gọi là dependency), do đó build tools còn được gọi là dependencies manager.

Hai công cụ phổ biến là Maven và Gradle, có thể tìm hiểu thêm.

5. Naming convention

Để code java được rõ ràng, thống nhất, nên tuân thủ một số quy ước đặt tên (naming convention) của java. Điều này không bắt buộc, nhưng được khuyến khích để code clean hơn.

Các đối tượng khác nhau trong code có cách đặt tên riêng:

  • Tên package: Lower case hoặc snake case java.util
  • Tên class: Pascal case và là danh từ MyClass
  • Tên interface: Pascal case và là tính từ Flyable
  • Tên object: Camel case obj, otherObj
  • Tên biến: Camel case myName
  • Tên hằng: Upper case PI_NUMBER
  • Tên method, Camel case, từ đầu tiên là động từ getName, toString

Java là ngôn ngữ phân biệt hoa thường.

C. Java basic

1. Simple program

Cấu trúc chung của một chương trình java. Khi đi sâu hơn, thì mỗi class chứa trong một file riêng cũng có cấu trúc như thế này.

// Chương trình thuộc package nào (chỉ thuộc 1 package)
package package_name;

// Import class vào để sử dụng (có thể import nhiều class)
import java.util.Scanner;  // Import một class
import java.util.*;  // Import toàn bộ package

// Định nghĩa thêm các class khác
class Util {
    ...
}

// Class chính, là public class duy nhất trong file
public class App {
    ...
    // Class chính phải có method main() như sau
    public static void main(String[] args) {
        ...
    }
}

Source code lưu trữ trong file App.java, mỗi file như vậy đều phải có một public class duy nhất, các class khác là phụ và chỉ được khai báo class.

Tên public class cần trùng với tên file, như ví dụ trên file là App.java thì tên class chính phải là App. Trong class chính, phải có một method main()public static void. Đây là nơi bắt đầu chạy toàn bộ chương trình.

2. Comment

Comment bị bỏ qua khi biên dịch. Java có 2 loại comment:

  • Single line comment: Từ dấu // cho tới hết dòng
  • Multi line comment (block comment): trong cặp /* */

Comment // dùng để comment, chú thích cho code, trong khi đó /* */ thường dùng để tạo document.

Và có thêm một loại comment nữa khá giống với /* */ là documentation comment, dùng để viết document với công cụ javadoc. Documentation comment có dạng /** */.

3. Import

Dùng từ khóa import để import một hoặc nhiều class vào chương trình. Các class có thể thuộc nhiều package khác nhau.

import java.util.*;  // Import toàn bộ package
import java.util.Scanner;  // Import một class Scanner vào

Nếu không import như trên, thì khi dùng trong chương trình cần chỉ định rõ package.Class, ví dụ như sau.

// Không dùng import (dài dòng)
java.util.Scanner sc = new java.util.Scanner(System.in);

// Dùng import (ngắn hơn)
import java.util.Scanner;
Scanner sc = new Scanner(System.in);

Câu lệnh import thường đặt ở ngoài và trên cùng, dưới khai báo package.

4. Variable & constant

Variable

Biến trong Java có 3 loại, mỗi loại nằm ở vị trí riêng:

  • Biến thực thể (instance variable): nằm trong class, không thuộc method nào. Biến này thuộc về các thực thể (instance - object) được tạo ra từ class.
  • Biến tĩnh (static variable): tương tự biến thực thể, nhưng có từ khóa static để đánh dấu biến thuộc về class, không phải object.
  • Biến cục bộ (local variable): được khai báo trong method.

Cú pháp khai báo tương tự C++. Có thể bỏ qua init value, và có thể khai báo nhiều biến cùng loại trên một dòng.

// Biến không khai báo ở đây
public class App {
    // Biến thực thể
    int instanceVar = 10;
    
    // Biến tĩnh
    static double staticVar;  // Không cần init value
    
    // Đây là method
    public static void main() {
        // Biến cục bộ
        int localVar = "Hello", name = "John";
    }
}

Constant

Hằng (constant) tương tự như khai báo biến. Trước đây dùng từ khóa const, nhưng được thay thế bằng final.

final float PI = 3.14;

Hằng không thể gán giá trị mới, và bắt buộc có init value khi khai báo. Đối với hằng số là object, thì các trường của object vẫn có thể thay đổi được.

5. Input & output

Output

Dùng các lệnh print của System.out để xuất output ra màn hình console (của cmd hoặc Eclipse console).

System.out.print("String " + a);  // In không xuống dòng
System.out.println("String " + a);  // In và xuống dòng
System.out.printf("String %d %d", a, b);
    // In với chuỗi format và pass value vào

Các lệnh trên nhận tham số là chuỗi, đối với printf() thì tham số sau là những value truyền vào. Do đó, cách viết sau là sai.

System.out.println(a, b, c);  // Sai
System.out.println(a + " " + b + " " + c);  // Đúng

Phải dùng phép nối chuỗi +, java sẽ tự động convert các biến thành chuỗi và nối lại mới hợp lệ.

Ngoài output stream là System.out còn có System.err tương tự, nhưng chỉ dùng xuất lỗi ra màn hình. Console trong eclipse sẽ hiển thị các văn bản xuất ra System.err bằng màu đỏ.

Input

Để nhập dữ liệu từ console, dùng class java.util.Scanner như sau.

import java.util.Scanner;
Scanner sc = new Scanner(System.in);
    // Tạo object scanner, và đọc dữ liệu từ System.in stream

Để đọc dữ liệu, dùng các method next_() phù hợp với loại dữ liệu cần đọc, ví dụ.

int a = sc.nextInt();  // Đọc số nguyên
double b = sc.nextDouble();  // Đọc số thực
String s = sc.nextLine();  // Đọc chuỗi thì đọc cả dòng

Sau khi dùng các lệnh nextInt(), nextFloat(),... nói chung là đọc số, thì dùng thêm một lệnh nextLine() phía sau để xóa kí tự \n thừa còn lại trong bộ đệm sau khi đọc số.

Các method đọc số chỉ lấy số, bỏ lại kí tự \n, làm cho lệnh đọc chuỗi phía sau bị trôi đi (kết quả chuỗi rỗng, nó chạy luôn mà không dừng lại để nhập). Do đó, dùng thêm nextLine() sau khi đọc số để xóa kí tự \n còn sót đi, để tránh lỗi trôi lệnh như trên.

int a = sc.nextInt();
sc.nextLine();
float b = sc.nextFloat();
sc.nextLine();

// Lệnh này không bị trôi đi
String s = sc.nextLine();

Cuối cùng là hai lưu ý khi sử dụng Scanner class để tránh lỗi:

  • Nên dùng một scanner duy nhất cho toàn bộ chương trình. Nhiều scanner cùng truy cập tới System.in stream thì sẽ gây xung đột (ngay cả khi một scanner đã đóng).
  • Khi dùng xong scanner cần gọi method close() để đóng input stream lại.

All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí