Java Core

Java Core hay còn gọi là Java SE (Standard Edition) là một trong những thành phần quan trọng nhất của Java.

Overview

Java là một ngôn ngữ lập trình hướng đối tượng (OOP) và dựa trên các lớp (class). Khác với phần lớn ngôn ngữ lập trình thông thường, thay vì biên dịch mã nguồn thành mã máy hoặc thông dịch mã nguồn khi chạy, Java được thiết kế để biên dịch mã nguồn thành bytecode, bytecode sau đó sẽ được môi trường thực thi (runtime environment) chạy.

Java được khởi đầu bởi James Gosling và bạn đồng nghiệp ở Sun Microsystems năm 1991. Ban đầu ngôn ngữ này được gọi là Oak (có nghĩa là cây sồi; do bên ngoài cơ quan của ông Gosling có trồng nhiều loại cây này), họ dự định ngôn ngữ đó thay cho C++, nhưng các tính năng giống Objective C. Không nên lẫn lộn Java với JavaScript, hai ngôn ngữ đó chỉ giống tên và loại cú pháp như C. Công ty Sun Microsystems đang giữ bản quyền và phát triển Java thường xuyên. Tháng 04/2011, công ty Sun Microsystems tiếp tục cho ra bản JDK 1.6.24.

Java được tạo ra với tiêu chí "Viết (code) một lần, thực thi khắp nơi" ("Write Once, Run Anywhere" (WORA)). Chương trình phần mềm viết bằng Java có thể chạy trên mọi nền tảng (platform) khác nhau thông qua một môi trường thực thi với điều kiện có môi trường thực thi thích hợp hỗ trợ nền tảng đó. Môi trường thực thi của Sun Microsystems hiện hỗ trợ Sun Solaris, Linux, Mac OS, FreeBSD & Windows. Ngoài ra, một số công ty, tổ chức cũng như cá nhân khác cũng phát triển môi trường thực thi Java cho những hệ điều hành khác như BEA, IBM, HP.... Trong đó đáng nói đến nhất là IBM Java Platform hỗ trợ Windows, Linux, AIX & z/OS.

Điểm mạnh của Java:
4 tính chất của lập trình hướng đối tượng trong Java

1. Tính đóng gói (encapsulation) và che giấu thông tin (information hiding)

2. Tính kế thừa (Inheritance)

3. Tính đa hình (polymorphism)

4. Tính trừu tượng (abstraction)

Java Hello world - Chương trình Java Hello world

Chúng ta hãy bắt đầu từ chương trình Java cổ điển nhất với một ứng dụng đơn giản. Chương trình sau đây cho phép hiển thị một thông điệp:

// This is a simple program called “HelloWorld.java”
class First {
    public static void main(String args[]) {
        System.out.println(“Hello World”);
    }
}

Tên file đóng vai trò rất quan trọng trong  Java. Chương trình biên dịch Java chấp nhận phần mở rộng .java. Trong Java các mã cần phải gom thành các lớp. Bởi vậy tên lớp và tên file có thể trùng nhau. Do đó Java phân biệt rạch ròi chữ in hoa và chữ in thường (case-sensitive). Nói chung tên lớp và tên file nên khác nhau. Ví dụ tên file 'First' và 'first' là hai file khác nhau.

Để biên dịch mã nguồn, ta xử dụng trình biên dịch java. Trình biên dịch xác định tên của file nguồn tại dòng lệnh như mô tả dưới đây:

javac First.Java

Trình dịch java tạo ra file First.class chứa các mã “bytecodes”. Những mã này chưa thể thực thi được. Để chương trình thực thi được ta cần dùng trình thông dịch “java interpreter”

Lệnh được thực hiện như sau:

java HelloWorld

Kết quả sẽ hiển thị trên màn hình như sau:

Hello World

Java Class - Lớp trong Java

Khi định nghĩa một lớp, bạn chỉ ra thuộc tính mà nó chứa được thể hiện bằng biến (Member Variable) và hành vi được thể hiện bởi hàm (Method):

Trong hầu hết các lớp, các biến thể hiện được truy cập bởi các phương thức định nghĩa trong lớp đó. Vì vậy, chính các phương thức quyết định dữ liệu của lớp có thể dùng như thế nào. Lớp định nghĩa một kiểu dữ liệu mới, dùng để tạo các đối tượng thuộc kiểu đó.

Dạng đầy đủ của một định nghĩa lớp như sau:

[public]

Lớp được truy xuất chung cho các Package khác, mặc định chỉ có các đoạn mã trong cùng một gói mới có quyền truy xuất nó

[abstract]

Lớp trừu tượng, không thể khởi tạo

[final]

Lớp hằng không có lớp con, không kế thừa

class ClassName

Tên lớp

[extends SuperClass]

Kế thừa lớp cha SuperClass

[implements Interfaces]

Giao diện được cài đặt bởi Class

{ //Member Variables Declarations

Khai báo các biến

// Methods Declarations

Khai báo các phương thức

}

 

Ví dụ: Tạo một lớp Box đơn giản với ba biến: width, height, depth

/* Định nghĩa lớp*/
class Box {

    double width;

    double height;

    double depth;

    public double getWidth() {
        return this.width;
    }
}

Java Object - Đối tượng trong Java

Object Class

Mặc định lớp Object là lớp cha của tất cả các lớp trong java. Nói cách khác nó là một lớp cáo nhất trong java.

java-object.png

Sử dụng lớp Object là hữu ích nếu bạn muốn tham chiếu bất kỳ đối tượng nào mà bạn chưa biết kiểu dữ liệu của đối tượng đó. Chú ý rằng biến tham chiếu của lớp cha có thể tham chiếu đến đối tượng của lớp con được gọi là upcasting.

Ví dụ: giả sử phương thức getObject() trả về một đối tượng nhưng nó có thể là bất kỳ kiểu nào như Employee, Student… chúng ta có thể sử dụng biến tham chiếu của lớp Object để tham chiếu tới đối tượng đó.

Object obj = getObject();//Chung ta khong biet doi tuong nao se duoc tra ve tu phuong thuc nay

Lớp Object cung cấp một vài cách xử lý chung cho tất cả các đối tượng như đối tượng có thể được so sánh, đối tượng có thể được cloned, đối tượng có thể được notified…

Các phương thức của lớp Object

Lớp Object cung cấp các phương thức như trong bảng sau:

Phương thức Mô tả
public final Class getClass() trả về đối tượng lớp Class của đối tượng hiện tại. Từ lớp Class đó có thể lấy được các thông tin metadata của class hiện tại.
public int hashCode() trả về số hashcode cho đối tượng hiện tại.
public boolean equals(Object obj) so sánh đối tượng đã cho với đối tượng hiện tại.
protected Object clone() throws CloneNotSupportedException tạo và trả về bản sao chép (clone) của đối tượng hiện tại.
public String toString() trả về chuỗi ký tự đại diện của đối tượng hiện tại.
public final void notify() đánh thức một luồng, đợi trình giám sát của đối tượng hiện tại.
public final void notifyAll() đánh thức tất cả các luồng. đợi trình giám sát của đối tượng hiện tại.
public final void wait(long timeout)throws InterruptedException làm cho Thread hiện tại đợi trong khoảng thời gian là số mili giây cụ thể, tới khi Thread khác thông báo (gọi phương thức notify() hoặc notifyAll()).
public final void wait(long timeout,int nanos)throws InterruptedException làm cho Thread hiện tại đợi trong khoảng thời gian là số mili giây và nano giây cụ thể, tới khi Thread khác thông báo (gọi phương thức notify() hoặc notifyAll()).
public final void wait()throws InterruptedException làm Thread hiện tại đợi, tới khi Thread khác thông báo (gọi phương thức notify() hoặc notifyAll()).
protected void finalize()throws Throwable Được gọi bởi Garbage Collector trước khi đối tượng bị dọn rác.
Khai báo Object

Một Object (đối tượng) nó chứa trong đó bao gồm các method (phương thức) và properties (thuộc tính) để tạo ra một kiểu dữ liệu hữu ích.

Object xác định hành vi của class. Khi bạn gửi một thông điệp vào một object, có nghĩa là bạn đang yêu cầu gọi các object hoặc thực hiện một trong những phương thức của nó.

Từ một quan điểm của lập trình hướng đối tượng, một đối tượng có thể là một cấu trúc dữ liệu (data structure), một biến (variable) hoặc một chức năng (function).

Object được phân bổ vị trí bộ nhớ. Các Object được thiết kế như class phân cấp.

ClassName ReferenceVariable = new ClassName();
Điểm khác biệt giữa Class và Object trong Java

Một Class là một Blueprint (kế hoạch) hay Prototype (nguyên mẫu) xác định biến và các phương thức (hay function) chung với tất cả các đối tượng cùng loại.

Một Object là một cụ thể của một Class. Các đối tượng thường được dùng để mô tả đối tượng trong thế giới thực mà bạn thấy hàng ngày.

Java Package - Gói trong Java

Package trong java được tạo bởi sự kết hợp của nhiều class hay interface. và trong package có thể chứa các package khác. Package thường chứa các class, interface hay sub-package có liên quan với nhau.

//Khai báo package
package vn.laptrinh;

public class Student {
    private int mark = 0;
    public Student(int m) {
        mark = m;
    }
    ...
}
Truy cập các thành phần trong package

Các class mà dự định sẽ được sử dụng bên ngoài package sẽ được khai báo là public.

Các package khác nhau có thể có các class trùng tên với nhau.

Nếu các package khác nhau mà có các class có tên trùng nhau thì khi sử dụng bắt buộc phải import đầy đủ tên package và tên class.

Có 4 kiểu truy cập vào package là private, protected, public và default:

Từ khóa Trong cùng class Trong cùng package Trong sub-package Package khác
private Không Không Không
default Không Không
protected Không
public

Java Interface - Giao diện trong Java

Khái niệm

Trong Java, Interface (giao diện) là một kiểu dữ liệu tham chiếu tương tự như Class (lớp) nhưng chỉ có thể chứa hằng số và tên các phương thức, không có phần thân phương thức (phương thức trừu tượng). Một lớp mô tả các thuộc tính và hành động của đối tượng còn Interface thì mô tả các hành động của lớp đó. Interface không thể được khởi tạo như lớp mà chỉ có thể được mở rộng từ các lớp khác hoặc được kế thừa từ các Interface khác.

Trong Interface, chúng ta không thể khai báo hàm tạo và Interface không thể kế thừa từ một lớp mà chỉ có thể được mở rộng từ lớp và một Interface có thể được kế thừa lại từ nhiều Interface khác.

Ngoại trừ lớp trừu tượng thì tất cả các lớp mở rộng Interface phải định nghĩa lại tất cả các phương thức của Interface.

Các đặc điểm của interface
Khai báo Interface

Để khai báo một Interface, sử dụng từ khóa interface

/* File name : Animal.java */
interface Animal {
   public void eat();
   public void travel();
}
Thực thi Interface
/* File name : MammalInt.java */
public class MammalInt implements Animal {

   public void eat() {
      System.out.println("Mammal eats");
   }

   public void travel() {
      System.out.println("Mammal travels");
   } 

   public int noOfLegs() {
      return 0;
   }

   public static void main(String args[]) {
      MammalInt m = new MammalInt();
      m.eat();
      m.travel();
   }
}
Kế thừa Interface

Một Interface có thể kế thừa từ Interface khác tương tự như cách mà một lớp kế thừa từ một lớp khác đó là chúng ta cũng sử dụng từ khóa extends. Một lớp mở rộng từ Interface con sẽ kế thừa tất cả các phương thức có trong Interface đó (tức là phương thức của Interface con và Interface cha của Interface mà lớp đó implement). Trong Java, 1 Interface có thể kế thừa từ nhiều Interface và các Interface này được ngăn cách nhau bởi dấu phẩy.

// Filename: Sports.java
public interface Sports {
   public void setHomeTeam(String name);
   public void setVisitingTeam(String name);
}

// Filename: Football.java
public interface Football extends Sports {
   public void homeTeamScored(int points);
   public void visitingTeamScored(int points);
   public void endOfQuarter(int quarter);
}

// Filename: Hockey.java
public interface Hockey extends Sports {
   public void homeGoalScored();
   public void visitingGoalScored();
   public void endOfPeriod(int period);
   public void overtimePeriod(int ot);
}
Đa kế thừa Interface

Khác với Class, Interface có thể kế thừa (extends) từ nhiều Interface khác

public interface Hockey extends Sports, Event

Java Abstract - Lớp và phương thức trừu tượng trong Java

1. Khái niệm

Tính trừu tượng là một tiến trình ẩn các chi tiết triển khai và chỉ hiển thị tính năng tới người dùng. Nói cách khác, nó chỉ hiển thị các thứ quan trọng tới người dùng và ẩn các chi tiết nội tại, ví dụ: để gửi tin nhắn, người dùng chỉ cần soạn text và gửi tin. Bạn không biết tiến trình xử lý nội tại về phân phối tin nhắn. Tính trừu tượng giúp bạn trọng tâm hơn vào đối tượng thay vì quan tâm đến cách nó thực hiện.

Trong trường hợp chúng ta muốn định nghĩa một lớp cha theo một cấu trúc trừu tượng cho trước mà không cần hiện thực đầy đủ các phương thức. Tức là ta muốn tạo một lớp cha có dạng chung cho tất cả các lớp con và để các lớp con hiện thực chi tiết. Khi đó, bạn muốn chắc chắn lớp con có chồng lắp phương thức.

Như vậy, những phương thức phải được chồng lắp trong lớp con gọi là phương thức trừu tượng, được khai báo abstract và không có phần thân phương thức.

Ví dụ: Trong các ứng dụng, bạn có thể vẽ đường tròn, hình chữ nhật, đoạn thẳng, đường cong… Mỗi một đối tượng đồ hoạ này đều chứa các thuộc tính (vị trí, nét viền) và hành vi (di chuyển, thay kích thước, vẽ). Bạn có thể khai báo chúng kế thừa lớp Graphic. Tuy nhiên vẽ một đường tròn là hoàn toàn khác với vẽ một hình chữ nhật, nên lớp Graphic được khai báo là lớp trừu tường, chứa các phương thức đã được hiện thực như moveTo, và phương thức trừu tượng như draw:

abstract class GraphicObject {
	int x, y;
	
	void moveTo(int newX, int newY) {
		// process
	}
	abstract void draw();
}

Mỗi một lớp con không trừu tượng của lớp Graphic như Circle, Rectangle sẽ phải cài đặt đầy đủ cho phương thức draw:

class Circle extends GraphicObject {
	void draw() {
		// process
	}
}
class Rectangle extends GraphicObject {
	void draw() {
		// process
	}
}
2. Phương thức trừu tượng trong Java

Một phương thức được khai báo là abstract và không có chi tiết triển khai thì đó là phương thức trừu tượng.

Nếu bạn muốn một lớp chứa một phương thức cụ thể nhưng bạn muốn triển khai thực sự phương thức đó để được quyết định bởi các lớp con, thì bạn có thể khai báo phương thức đó trong lớp cha ở dạng abstract.

Từ khóa abstract được sử dụng để khai báo một phương thức dạng abstract. Một phương thức abstract không có thân phương thức.

Phương thức abstract sẽ không có định nghĩa, chỉ gồm tên phương thức:

abstract void draw();
3. Kế thừa lớp Abstract trong Java

Trong ví dụ này, Shape là lớp trừu tượng, trình triển khai của nó được cung cấp bởi lớp Rectangle và lớp Circle. Hai lớp này kế thừa lớp trừu tượng Shape.

// lop truu tuong Shape
abstract class Shape {
 abstract void draw();
}

//Trong tinh huong nay, trinh trien khai duoc cung cap boi ai do, vi du: nguoi su dung cuoi cung nao do  
class Rectangle extends Shape {
 void draw() {
  System.out.println("Ve hinh chu nhat");
 }
}

class Circle1 extends Shape {
 void draw() {
  System.out.println("Ve hinh tron");
 }
}

//Trong tinh huong nay, phuong thuc duoc goi boi lap trinh vien hoac nguoi dung  
class TestAbstraction1 {
 public static void main(String args[]) {
  Shape s = new Circle1(); //Trong tinh huong nay, doi tuong duoc cung cap thong qua phuong thuc, chang han nhu getShape()  
  s.draw();
 }
}
4. Đặc điểm của Abstract Class
5. Đặc điểm của Abstract Method

Java Data Types - Kiểu dữ liệu trong Java

Java cung cấp một các kiểu dữ liệu. Chúng được hỗ trợ trên tất cả các nền tảng. Ví dụ, dữ liệu loại int (integer) của Java được thể hiện bằng 4 bytes trong bộ nhớ của tất cả các loại máy bất luận ở đâu chạy chương trình Java. Bởi vậy các chương trình Java không cần phải thay đổi khi chạy trên các nền tảng khác nhau.

Trong Java kiểu dữ liệu được chia thành hai loại:

Kiểu dữ liệu nguyên thủy

Java cung cấp tám kiểu dữ liệu nguyên thuỷ:

Kiểu dữ liệu

Độ dài theo số bit

Phạm vi

Mô tả

byte

8

-128 đến 127

Số liệu kiểu byte là một loại điển hình dùng để lưu trữ một giá tri bằng một byte. Chúng được sử dụng rộng rãi khi xử lý một file văn bản

Char

16

‘\uoooo’ to ’u\ffff ’

Kiểu Char sử dụng để lưu tên hoặc các dữ liệu ký tự .Ví dụ tên ngườI lao động

Boolean

1

“True” hoặc “False”

Dữ liệu boolean dùng để lưu các giá trị “Đúng” hoặc “sai” Ví dụ : Người lao đông có đáp ứng được yêu cầu của công ty hay không ?

short

16

-32768 đến 32767

Kiểu short dùng để lưu các số có giá trị nhỏ dưới 32767.Ví dụ số lượng người lao động.

Int

32

-2,147,483,648 đến +2,147,483,648

Kiểu int dùng để lưu một số có giá trị lớn đến 2,147,483,648.Ví dụ tổng lương mà công ty phải trả cho nhân viên.

Long

64

-9,223,372,036’854,775,808 đến +9,223,372,036’854,775,808

Kiểu long được sử dụng để lưu một số cố giá trị rất lớn đến 9,223,372,036’854,775,808 .Ví dụ dân số của một nước

Float

32    

-3.40292347E+38 đến +3.40292347E+38

Kiểu float dùng để lưu các số thập phân đến 3.40292347E+38 Ví dụ : giá thành sản phẩm

double

64

-1,79769313486231570E+308 đến +1,79769313486231570E+308

Kiểu double dùng để lưu các số thập phân có giá trị lớn đến

1,79769313486231570E+308 Ví dụ giá trị tín dụng của ngân hàng nhà nước.

Kiểu dữ liệu tham chiếu

Trong Java có 3 kiểu dữ liệu tham chiếu

Kiểu dữ liệu

Mô tả

Mảng (Array)

Tập hợp các dữ liệu cùng loại.Ví dụ : tên sinh viên

Lớp (Class)

Tập hợp các biến và các phương thức.Ví dụ : lớp “Sinhviên” chứa toàn bộ các chi tiết của  một sinh viên và các phương thức thực thi trên các chi tiết đó.

Giao diện (Interface)

Là một lớp trừu tượng được tạo ra để bổ sung cho các kế thừa đa lớp trong Java.

Ép kiểu (Type casting)

Có thể bạn sẽ gặp tình huống khi cộng một biến có dạng integer với một biến có dạng float. Để xử lý tình huống này, Java sử dụng tính năng ép kiểu (type casting) của các phần mềm trước đó C, C++. Lúc này một kiểu dữ liệu sẽ chuyển đổi sang kiểu khác. Khi sử dụng tính chất này, bạn cần thận trọng vì khi điều chỉnh dữ liệu có thể bị mất.

Đoạn mã sau đây thực hiện phép cộng một giá trị dấu phẩy động (float) với một giá trị nguyên (integer).

Float c=34.896751F;

Int b = (int)c +10;

Đầu tiên giá trị dấu phảy động c được đổi thành giá trị nguyên 34. Sau đó nó được cộng với 10 và kết quả là giá trị 44 được lưu vào b.

Sự nới rộng (widening) – quá trình làm tròn số theo hướng nới rộng không làm mất thông tin về độ lớn của mỗi giá trị:

Java Variables - Kiểu biến trong Java

Khái niệm

Các ứng dụng sử dụng các biến để lưu trữ các dữ liệu cần thiết hoặc các dữ liệu được tạo ra trong quá trình thực thi chương trình. Các biến được xác định bởi một tên biến và có một phạm vi tác động. Phạm vi tác động của biến được xác định một cách rõ ràng trong chương trình. Mỗi biến được khai báo trong một khối chương trình chỉ có tác động trong phạm vi khối đó, không có ý nghĩa và không được phép truy nhập từ bên ngoài khối.

variable.png

int data=50;//Here data is variable

Việc khai báo một biến bao gồm 3 thành phần: kiểu biến, tên của nó và giá trị ban đầu được gán cho biến (không bắt buộc). Để khai báo nhiều biến ta sử dụng dấu phẩy để phân cách các biến. Khi khai báo biến, luôn nhớ rằng Java phân biệt chữ thường và chữ in hoa (case-sensitive).

Cú pháp
Datatype indentifier [=value] [, indentifier[=value]... ];

Để khai báo một biến nguyên (int) có tên là counter dùng để lưu giá trị ban đầu là 1, ta có thể thực hiện phát biểu sau đây:

int counter = 1;

Java có những yêu cầu hạn chế đặt tên biến mà bạn có thể gán giá trị vào. Những hạn chế này cũng giống các hạn chế khi đặt tên cho các định danh mà ta đã thảo luận ở các phần trước của chương này.

Các loại biến

types-of-variables1.png

1. Biến local - Local variable

class Simple {
	public static void main(String[] args) {
		int a = 10;		// local variable
		float f = a;	// local variable
		System.out.println(a);
		System.out.println(f);
	}
}

2. Biến toàn cục - Instance variable

class A {
	int data = 50; //instance variable  
	void method() {
		System.out.println(data);
	}
} //end of class

3. Biến static - Static variable

class A {
	static int m = 100; //static variable  
	void method() {
		System.out.println(m);
	}
} //end of class

Java Method - Phương thức trong Java

Khái niệm

Phương thức xác định giao diện cho phần lớn các lớp. Trong khi đó Java cho phép bạn định nghĩa các lớp mà không cần phương thức. Bạn cần định nghĩa phương thức truy cập dữ liệu mà bạn đã lưu trong một lớp.

Phương thức được định nghĩa như một hành động hoặc một tác vụ thật sự của đối tượng. Nó còn được định nghĩa như một hành vi mà trên đó các thao tác cần thiết được thực thi.

Cú pháp
access_specifier modifier datatype method_name(parameter_list)
{
	//body of method
}

Trong đó:

class Temp {
    static int x = 10; //variable
    public static void show() //method
    {
        System.out.println(x);
    }
    public static void main(String args[]) {
        Temp t = new Temp(); // object 1
        t.show(); //method call
        Temp t1 = new Temp(); // object 2
        t1.x = 20;
        t1.show();
    }
}
Chỉ định truy cập phương thức - Access specifier method

Các chỉ định truy xuất dùng để giới hạn khả năng truy nhập vào một phương thức. Java cung cấp các chỉ định truy xuất sau đây:

Loại phương thức - Modifier method

Các bổ nghĩa loại phương thức cho phép ta thiết lập các thuộc tính của phương thức. Java cung cấp các bổ nghĩa sau:

Nạp chồng - Overloading method

Phương thức được nạp chồng (overload) là phương thức trong cùng một lớp, có cùng một tên song có danh sách các tham số khác nhau. Sử dụng việc nạp chồng phương thức để thực thi các phương thức giống nhau đối với các kiểu dữ liệu khác nhau. Ví dụ phương thức swap() có thể bị nạp chồng (overload) bởi các tham số của kiểu dữ liệu khác như integer, double và float.

Phương thức nạp chồng là một hình thức đa hình (polymorphism) trong quá trình biên dịch (compile).

Đoạn chương trình sau mô tả nạp chồng phương thức được thực hiện như thế nào:

//defined once
protected void perfomTask(double salary) {
    System.out.prinln("Salary is: "+salary);….
}
//overloaded –defined the second time with different parameters
protected void performTask(double salary, int bonus) {
    System.out.println("Total Salary is: " + salary + bonus);
}
Ghi đè - Overriding method

Phương thức được ghi đè (overriden) là phương thức có mặt ở lớp cha (superclasss) cũng như ở các lớp kế thừa. Phương thức này cho phép một lớp tổng quát chỉ định các phương thức sẽ là phương thức chung trong các lớp con. Ví dụ lớp xác định phương thức tổng quát 'area()'. Phương thức này có thể được hiện thực trong một lớp con để tìm diện tích một hình cụ thể như hình chữ nhật, hình vuông...

Phương thức ghi đè là một hình thức đa hình trong quá trình thực thi (runtime).

Các đoạn mã sau đây mô tả việc thực thi ghi đè phương thức trong Java:

class SupperClass // Tạo lớp cơ bản
{
    int a;
    SuperClass() // constuctor
    {}
    SuperClass(int b) //overloaded  constructor
    {
        a = b;
    }
    class Subclass Extends SuperClass { // derriving a class
        int a;
        SubClass(int a) { //subclass constructor
            This.a;
        }
        public void message() { // overiding the base class message()
            System.out.prinln("In the sub class");
        }
    }
}

Bây giờ chúng ta sẽ tạo ra một đối tượng lớp cha và gán một lớp nhỏ tham chiếu đến nó như sau:

SuperClasss spObj = new Subclass(22);

Câu lệnh 'spObj.message' thuộc phương thức nhóm con. Ở đây kiểu đối tượng được gán cho 'spObj' sẽ chỉ được xác định khi chương trình thực thi. Điều này được biết dưới khái niệm 'liên kết động' (dinamic binding).

Phương thức khởi tạo lớp - Constructor method

Phương thức khởi tạo lớp là một loại phương thức đặc biệt rất khác với các kiểu khởi tạo cơ bản. Nó không có kiểu trả về. Nó có tên trùng với tên của lớp. Hàm khởi tạo lớp thực thi như một phương thức hoặc một chức năng bình thường song nó không trả về bất cứ một giá trị nào. Nói chung chúng được dùng để khởi tạo các biến thành viên của một lớp và nó được gọi bất cứ lúc nào bạn tạo ra đối tượng của lớp đó.

Phương thức khởi tạo lớp có hai loại:

Bạn có thể định nghĩa nhiều phương thức khởi tạo cho một lớp. Giống như các phương thức khác, phương thức khởi tạo lớp có thể bị nạp chồng (overload)

Ví dụ một phương thức khởi tạo:

Đoạn mã sau đây định nghĩa một phương thức khởi tạo tường minh (explicit) cho một lớp Employee. Phương thức khởi tạo bao gồm tên và tuổi. Chúng được coi như các tham số và gán các giá trị của chúng vào các biến của lớp. Chú ý rằng từ khoá 'this' được sử dụng để tham chiếu đến đối tượng hiện hành của lớp.

Class Employee {
    String name;
    int age;
    Employee(String varname, int varage) {
        this.name = varname;
        this.age = varage;
    }
    public static void main(String arg[]) {
        Employee e = new Employee("Allen", 30);
    }
}

Java Operators - Toán tử trong Java

Một chương trình thực tế bao hàm việc tạo ra các biến. Các toán tử kết hợp các giá trị đơn giản hoặc các biểu thức con thành những biểu thức mới, phức tạp hơn và có thể trả về các giá trị. Điều này có hàm ý tạo ra các toán tử luận lý, số học, quan hệ và so sánh trên các biểu thức.

Java cung cấp nhiều dạng toán tử. Chúng bao gồm:

1. Các toán tử số học

Các toán hạng của các toán tử số học phải ở dạng số. Các toán hạng kiểu Boolean không sử dụng được, song các toán hạng ký tự cho phép sử dụng loại toán tử này. Một vài kiểu toán tử được liệt kê trong bảng dưới đây.

Toán tử

Mô tả

+

Cộng.Trả về giá trị tổng hai toán hạng

Ví dụ 5+3  trả về kết quả là 8

-

Trừ

Trả về giá trị khác nhau giữa hai toán hạng hoặc giá trị phủ định của toán hạng. Ví dụ 5-3 kết quả là 2 và –10 trả về giá trị âm của 10

*

Nhân

Trả về giá trị là tích hai toán hạng. Ví dụ 5*3 kết quả là 15

/

Chia

Trả về giá trị là thương của phép chia

Ví dụ 6/3 kết quả là 2

%

Phép lấy modulo

Giá trị trả về là phần dư của toán tử chia

Ví dụ 10%3  giá trị trả về là 1

++

Tăng dần

Tăng giá trị của biến lên 1. Ví dụ a++ tương đương với a= a+1

--

Giảm dần

Giảm giá trị của biến 1 đơn vị. Ví dụ a-- tương đương với a=a-1

+=

Cộng và gán giá trị

Cộng các giá trị của toán hạng bên trái vào toán hạng bên phải và gán giá trị trả về vào toán hạng bên trái.

Ví dụ c+=a tương đương c=c+a

-=

Trừ và gán giá trị

Trừ các giá trị của toán hạng bên trái vào toán toán hạng bên phải và gán giá trị trả về vào toán hạng bên trái.

Ví dụ c-= a tương đương vớI c=c-a

*=

Nhân và gán

Nhân các giá trị của toán hạng bên trái với toán toán hạng bên phải và gán giá trị trả về vào toán hạng bên trái.

Ví dụ c *= a  tương đương với c=c*a

/=

Chia và gán

Chia giá trị của toán hạng bên trái cho toán toán hạng bên phải và gán giá trị trả về vào toán hạng bên trái.

Ví dụ c /= a  tương đương với c=c/a

%=

Lấy  số dư và gán

Chia giá trị của toán hạng bên trái cho toán toán hạng bên phải và gán giá trị số dư vào toán hạng bên trái.

Ví dụ c%=a tương đương với c=c%a

Ví dụ:

class ArithmeticOp {
 public static void main(String args[]) {
  int p = 5, q = 12, r = 20, s;
  s = p + q;
  System.out.println(“p + q is” + s);
  s = p % q;
  System.out.println(“p % q is” + s);
  s *= r;
  System.out.println(“s *= r is” + s);
  System.out.println(“Value of p before operation is” + p);
  p++;
  System.out.println(“Value of p after operation is” + p);
  double x = 25.75, y = 14.25, z;
  z = x - y;
  System.out.println(“x - y is” + z);
  z -= 2.50;
  System.out.println(“z -= 2.50 is“ + z);
  System.out.println(“Value of z before operation is” + z);
  z--;
  System.out.println(“Value of z after operation is” + z);
  Z = x / y;
  System.out.println(“x / y is” + z);
 }
}

Output:

p+q  is 17
p%q is 5
s*=r is 100
Value of p before operation is 9.0
Value of z  after operation is 8.0
x/y is 1.8070175438596429
2. Toán tử Bit

Các toán tử dang Bit cho phép ta tạo những Bit riêng biệt trong các kiểu dữ liệu nguyên thuỷ. Toán tử Bit dựa trên cơ sở đại số Boolean. Nó thực hiện phép tính trên hai đối số là các bit để tạo ra một kết qủa mới. Một vài dạng toán tử kiểu này được liệt kê dưới đây

Toán tử

Mô tả

~

 Phủ định  (NOT)

Trả về giá trị phủ định của một số. Ví dụ a=10 thì ~a=-10

&

Toán tử AND

Trả về giá trị là 1 nếu các toán hạng là 1 và 0 trong các trường hợp khác. Ví dụ nếu a=1và b=0 thì a&b trả về giá trị 0

I

Toán tử OR

Trả về giá trị là 1 nếu một trong các toán hạng là 1 và 0 trong các trường hợp khác. Ví dụ nếu a=1và b=0 thì aIb trả về giá trị 1

^

Exclusive OR

Trả về giá trị là 1 nếu chỉ một trong các toán hạng là 1 và trả về 0 trong các trường hợp khác. Ví dụ nếu a=1và b=1 thì a^b trả về giá trị 0

>> 

Dịch sang phải

Chuyển toàn bộ các bít cuả một số sang phải một vị trí, giữ nguyên dấu của số âm. Toán hạng bên trái là số bị dịch còn số bên phải chỉ số vị trí mà các bít cần dịch.

Ví dụ x=37 tức là 00011111 vậy x>>2 sẽ là 00000111.

<< 

Dịch sang trái

Chuyển toàn bộ các bít cuả một số sang trái một vị trí, giữ nguyên dấu cuả số âm. Toán hạng bên trái là số bị dịch còn số bên phải chỉ số vị trí mà các bít cần dịch.

3. Các toán tử quan hệ

Các toán tử quan hệ kiểm tra mối quan hệ giữa hai toán hạng. Kết quả của một biểu thức có dùng các toán tử quan hệ là những giá trị Boolean (logic "đúng" hoặc "sai"). Các toán tử quan hệ được sử dụng trong các cấu trúc điều khiển.

Toán tử

Mô tả

= =

So sánh bằng

Toán tử này kiểm tra sự tương đương của hai toán hạng

Ví dụ if (a= =b) trả về giá tri “True” nếu giá trị của a và b như nhau

!=

So sánh khác

Kiểm tra sự khác nhau của hai toán hạng

Ví dụ if(a!=b)  Trả về giá trị “true” nếu a khác b

>

Lớn hơn

Kiểm tra giá trị của toán hạng bên phải lớn hơn toán hạng bên trái hay không

Ví du  if(a>b) . Trả về giá trị “true” nếu a lớn hơn b,ngựơc lai (nhỏ hơn hoặc bằng ), trả về ‘False’

Nhỏ hơn

Kiểm tra giá trị của toán hạng bên phải có nhỏ hơn toán hạng bên trái hay không

Ví du  if(a<b) . Trả về giá trị “true” nếu a  nhỏ hơn b, ngựơc lại (lớn hơn hoặc bằng trả về ‘False’

>=

Lớn hơn hoặc bằng

Kiểm tra giá trị của toán hạng bên phải có lớn hơn hoặc bằng toán hạng bên trái hay không

Ví du  if(a>=b) . Trả về giá trị "true" nếu a lớn hơn hoặc  bằng b, ngựơc lại (nhỏ hơn trả về ‘False’

<=

Nhỏ hơn hoặc bằng

Kiểm tra giá trị của toán hạng bên phải có nhỏ hơn hoặc bằng toán hạng bên trái hay không

Ví du  if(a<=b) . Trả về giá trị “true” nếu a nhỏ hơn hoặc  bằng b , ngựơc lại (lớn hơn trả về 'False'

Ví dụ:

class RelationalOp {
 public static void main(String args[]) {
  float a = 10.0 F;
  double b = 10.0;
  if (a = = b)
   System.out.println(a and b are equal”);
  else
   System.out.println("a and b are not equal");
 }
}

Output:

a and b are not equal

Trong chương trình trên cả a và b là những số có dấu phẩy động, dạng dữ liệu có khác nhau, a là kiểu float còn b là kiểu double. Tuy vậy chúng không phải là cùng một kiểu. Bởi vậy khi kiểm tra giá trị của các toán hạng, kiểu dữ liệu cần phải được kiểm tra.

4. Các toán tử logic

Các toán tử logic làm việc với các toán hạng Boolean. Một vài toán tử kiểu này được chỉ ra dưới đây:

Toán tử

Mô tả

&

Và (AND)

Trả về một giá trị “Đúng” (True) nếu chỉ khi cả hai toán tử có giá trị “True”

Ví dụ: if(sciencemarks>90) AND (mathmarks>75) thì gán “Y” cho biến “được nhận học bổng”

I

Hoặc (OR)

Trả về giá trị “True” nếu một giá trị  là True hoặc cả hai đều là True

Ví dụ  Nếu  age_category is ‘Senior_citizen’ OR special_category is ‘handicapped’ thì giảm giá tua lữ hành. Giá cũng sẽ được giảm nếu cả hai điều kiện đều được thỏa mãn

^

XOR

Trả về giá trị True nếu chỉ một trong các giá trị là True, các trường hợp còn lại cho giá trị False (sai)

!

Toán hạng đơn tử NOT. Chuyển giá trị từ True sang False và ngược lại.

Ví dụ: Quá trình thực thi các dòng lệnh tiếp tục cho đến khi kết thúc chương trình.

5. Các toán tử điều kiện

Toán tử điều kiện là một loại toán tử đặc biệt vì nó gồm ba thành phần cấu thành biểu thức điều kiện:

Cú pháp:
biểu thức 1?biểu thức 2: biểu thức 3;
biểu thức 1
Điều kiện luận lý (Boolean) mà nó trả về giá trị True hoặc False
biểu thức 2
Giá trị trả về nếu biểu thức 1 xác định là True
biểu thức 3
Giá trị trả về nếu biểu thức 1 xác định là False

Câu lệnh sau đây kiểm tra có những người đi làm bằng vé tháng có tuổi lớn hơn 65 không và gán một tiêu chuẩn cho họ. Nếu những người này có tuổi là 55, tiêu chuẩn gán là "Regular"

CommuterCategory=(CommuterAge>65)?"Senior Citizen": "Regular"
6. Toán tử gán

Toán tử gán (=) dùng để gán một giá trị vào một biến. Bạn nên gán nhiều giá trị đến nhiều biến cùng một lúc.
Ví dụ đoạn lệnh sau gán một giá trị cho biến num. Thì giá trị trong biến num được gán cho nhiều biến trên một dòng lệnh đơn.

int num = 20000;
int p,q,r,s;
p=q=r=s=num;

Dòng lệnh cuối cùng được thực hiện từ phải qua trái. Đầu tiên giá trị ở biến num được gán cho 's', sau đó giá trị của 's' được gán cho 'r' và cứ tiếp như vậy.

7. Thứ tự ưu tiên của các toán tử

Các biểu thức được viết ra nói chung gồm nhiều toán tử. Thứ tự ưu tiên quyết định trật tự thực hiện các toán tử trên các biểu thức. Bảng dưới đây liệt kê thứ tự thực hiện các toán tử trong Java

Thứ tự

Toán tử

1.

Các toán tử đơn như +,-,++,--

2.

Các toán tử số học và các toán tử dịch như *,/,+,-,<<,>>

3.

Các toán tử quan hệ như >,<,>=,<=,= =,!=

4.

Các toán tử logic và Bit như &&,II,&,I,^

5.

Các toán tử gán như =,*=,/=,+=,-=

Để thay đổi thứ tự ưu tiên trên một biểu thức, bạn có thể sử dụng dấu ngoặc đơn (). Từng phần của biểu thức được giới hạn trong ngoặc đơn được thực hiện trước tiên. Nếu bạn sử dùng nhiều ngoặc đơn lồng nhau thì toán tử nằm trong ngoặc đơn phía trong sẽ thực thi trước, sau đó đến các vòng phía ngoài. Nhưng trong phạm vi một ngoặc đơn thì quy tắc thứ tự ưu tiên vẫn giữ nguyên tác dụng.

Java Arrays - Mảng trong Java

Khái niệm

Java cung cấp cấu trúc dữ liệu, gọi là mảng (array), để lưu trữ các phần tử có cùng kiểu dữ liệu. Mảng được sử dụng để lưu trữ bộ sưu tập dữ liệu, nhưng người ta thường biết đến mảng lưu trữ các phần tử có cùng kiểu dữ liệu nhiều hơn.

Thay vì khai báo từng biến một, chẳng hạn như số 0, số 1... và số 99, bạn có thể khai báo một biến mảng như: số và sau đó sử dụng các số [0], số [1]... và số [99] để biểu diễn từng biến một.

Khai báo mảng trong Java

Để sử dụng một mảng trong chương trình, trước hết bạn phải khai báo biến để tham chiếu mảng, và phải chỉ định loại mảng mà biến có thể tham chiếu. Dưới đây là cú pháp khai báo biến mảng trong Java:

Cú pháp:

dataType[] arrayRefVar = new dataType[arraySize];

Hoặc:

dataType arrayRefVar[] = new dataType[arraySize];

Hoặc ngoài ra bạn có thể tạo các mảng trong Java bằng cách sử dụng cú pháp dưới đây:

dataType[] arrayRefVar = {value0, value1, ..., valuek};

Lưu ý:

Cú pháp dataType[] arrayRefVar được ưu tiên hơn. Còn cú pháp dataType arrayRefVar[] có nguồn gốc từ ngôn ngữ C/C++ và được chấp nhận trong Java.

Phương thức hoạt động của mảng

Một mảng sẽ có chỉ số index từ 0 đến n - 1 (n là số lượng phần tử của mảng).

Ví dụ: Khởi tạo mảng số nguyên 10 phần tử, có giá trị tuần tự từ 1 đến 10. Và xuất các giá trị của mảng ra màn hình console.

public class Main {
 
    public static void main(String[] args) {
 
        int[] arr = new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i] = i + 1;
        }
 
        for(int item : arr) {
            System.out.print(item + " ");
        }
 
    }
}

arrays-in-java-.jpg

Truy xuất các phần tử của mảng

Chúng ta có 2 cách để truy xuất các phần tử của mảng:

Truy xuất trực tiếp

public class Main {
 
    public static void main(String[] args) {
 
        // Khoi tao mang
        int[] arr = new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i] = i + 1;
        }
 
        System.out.println(arr[5]);
 
    }
}

Chú ý nếu index vượt ra khoảng chưá của mảng thì chúng ta sẽ nhận một exception. Khoảng hợp lệ 0 đến n – 1 (n số lượng phần tử của mảng).

Khi mình truy xuất arr[10] là vị trí không hợp lệ mình sẽ được kết quả sau:

Exception in thread “main” ava.lang.ArrayIndexOutOfBoundsException: 10
at Main.main(Main.java:11)

Truy xuất tuần tự

- Sử dụng vòng lặp for:

for(int i = 0; i < 10; i++) {
    System.out.println(i);
}

- Sử dụng foreach:

for(int item : arr) {
	System.out.println(item);
}
Passing by reference

Khi bạn truyền java vào một method, các thay đổi trên mảng sẽ được cập sau khi kết thúc method.

Ví dụ: Tăng mỗi phần tử trong mảng lên mảng và in ra màn hình console.

public class Main {
 
    public static void main(String[] args) {
 
        // Khoi tao mang
        int[] arr = new int[10];
        for (int i = 0; i < 10; i++) {
            arr[i] = i + 1;
        }
 
        increment(arr);
 
        for(int item : arr) {
            System.out.print(item + " ");
        }
    }
 
    public static void increment(int[] arr) {
        for (int i = 0; i < 10; i++) {
            arr[i] += 1;
        }
    }
}

Output: 2 3 4 5 6 7 8 9 10 11

Chúng ta thấy hàm increment() đã thay đổi các giá trị trong mảng. Vì vậy ở hàm main truy xuất được mảng đã được update bởi increment().

Thao tác cơ bản trên array

Java cung cấp cho chúng ta một số thao tác cơ bản mà chúng ta thường xuyên sử dụng như sắp xếp, so sánh etc, đựơc implement trong class java.util.Arrays.

STT Method
1

public static int binarySeach(Object[] a, Object key)

Tìm kiếm phần tử key trong mảng, điều kiện mảng đã được sắp xếp

2

public static boolean equals(long[] a, long[] a2)

So sánh 2 mảng, trả về true nếu bằng nhau(index, value), ngược lại false

3

public static void fill(int[] a. int val)

Khởi tạo mảng với giá trị được gán sẵn val

4

public static void sort(Object[] a)

Sắp xếp mảng tăng dần

Java Keywords - Các từ khóa trong Java

Keywords (Từ khóa) là những từ đã được định nghĩa cho trình biên dịch Java. Chúng có ý nghĩa đặc biệt cho trình biên dịch. Từ khóa Java phải có trong thông tin của bạn vì bạn không thể sử dụng chúng làm biến, lớp hoặc tên phương thức.

Bạn không thể sử dụng từ khóa làm định danh trong các chương trình Java của mình, các từ dành riêng trong thư viện Java và được sử dụng để thực hiện thao tác nội bộ.

abstract assert boolean break
byte case catch char
class const continue default
do double else enum
extends final finally float
for goto if implements
import instanceof int interface
long native new package
private protected public return
short static strictfp super
switch synchronized this throw
throws transient try void
volatile while  true  false
null      
  1. abstract - Chỉ ra rằng class hoặc phương thức sẽ phải thực thi sau đó trong một subclass.
  2. assert - Là keyword có từ Java 1.4 sử dụng để kiểm tra một biểu thức có đúng hay không, thường sử dụng cho việc viết code unit test. Trong Java sử dụng assert có 2 cách viết.
  3. boolean - Kiểu dữ liệu chỉ có giá trị True và False
  4. break – A control statement for breaking out of loops
  5. byte – A data type that can hold 8-bit data values
  6. case – Used in switch statements to mark blocks of text
  7. catch – Catches exceptions generated by try statements
  8. char – A data type that can hold unsigned 16-bit Unicode characters
  9. class -Declares a new class
  10. continue -Sends control back outside a loop
  11. default -Specifies the default block of code in a switch statement
  12. do -Starts a do-while loop
  13. double – A data type that can hold 64-bit floating-point numbers
  14. else – Indicates alternative branches in an if statement
  15. enum – A Java keyword used to declare an enumerated type. Enumerations extend the base class.
  16. extends -Indicates that a class is derived from another class or interface
  17. final -Indicates that a variable holds a constant value or that a method will not be overridden
  18. finally -Indicates a block of code in a try-catch structure that will always be executed
  19. float -A data type that holds a 32-bit floating-point number
  20. for -Used to start a for loop
  21. if -Tests a true/false expression and branches accordingly
  22. implements -Specifies that a class implements an interface
  23. import -References other classes
  24. instanceof -Indicates whether an object is an instance of a specific class or implements an interface
  25. int – A data type that can hold a 32-bit signed integer
  26. interface – Declares an interface
  27. long – A data type that holds a 64-bit integer
  28. native -Specifies that a method is implemented with native (platform-specific) code
  29. new – Creates new objects
  30. null -Indicates that a reference does not refer to anything
  31. package – Declares a Java package
  32. private -An access specifier indicating that a method or variable may be accessed only in the class it’s declared in
  33. protected – An access specifier indicating that a method or variable may only be accessed in the class it’s declared in (or a subclass of the class it’s declared in or other classes in the same package)
  34. public – An access specifier used for classes, interfaces, methods, and variables indicating that an item is accessible throughout the application (or where the class that defines it is accessible)
  35. return -Sends control and possibly a return value back from a called method
  36. short – A data type that can hold a 16-bit integer
  37. static -Indicates that a variable or method is a class method (rather than being limited to one particular object)
  38. strictfp - Là keyword đảm bảo cho bạn sẽ nhận một kết quả như nhau khi thực hiện các toán tử với số thập phân trên các platform’s hardware khác nhau. Keyword này có thể được sử dụng cho classes, interfaces and methods.
  39. super – Refers to a class’s base class (used in a method or class constructor)
  40. switch -A statement that executes code based on a test value
  41. synchronized -Specifies critical sections or methods in multithreaded code
  42. this -Refers to the current object in a method or constructor
  43. throw – Creates an exception
  44. throws -Indicates what exceptions may be thrown by a method
  45. transient - Là keyword sẽ thông báo cho JVM biết đối tượng được transient sẽ không được serialization khi truyền qua IO (cũng có nghĩa là đối tượng đó sẽ không được chuyển qua mạng)
  46. try -Starts a block of code that will be tested for exceptions
  47. void -Specifies that a method does not have a return value
  48. volatile -Indicates that a variable may change asynchronously
  49. while -Starts a while loop

** The keywords const and goto are reserved, even they are not currently in use.

** true, false and null không phải là các từ dành riêng nhưng không thể được sử dụng làm định danh, bởi vì nó là giá trị của các kiểu dữ liệu.

Java If-else statement - Cấu trúc If-else trong Java

Câu lệnh if-else kiểm tra kết quả của một điều kiện và thực thi một thao tác phù hợp trên cơ sở kết quả đó. Dạng của câu lệnh if-else rất đơn giản.

if_statement_flow_chart_diagram.png

Cú pháp:

if (conditon) {
	action 1 statements;
}
else {
	action 2 statements;
}

Trong đó:

Ví dụ:

Đoạn chương trình sau kiểm tra xem các số là chẵn hay lẻ và hiển thị thông báo phù hợp:

class CheckNumber {
    public static void main(String args[] {
		int num = 10;
		if (num % 2 == 0)
			System.out.println(num + " is an even number");
		else
			System.out.println(num + " is an odd number");
	}
}

Ở đoạn chương trình trên num được gán giá trị nguyên là 10. Trong câu lệnh if-else điều kiện num %2 trả về giá trị 0 và điều kiện thực hiện là True. Thông báo 10 is an even number được in ra. Lưu ý rằng cho đến giờ chỉ có một câu lệnh tác động được viết trong đoạn if và else, bởi vậy không cần phải được đưa vào dấu ngoặc móc.

Java If-else-if statement - Cấu trúc If-else-if trong Java

Câu lệnh if-else-if cũng kiểm tra điều kiện của các giá trị để thực thi khối lệnh. Nếu giá trị điều kiện if là True thì chỉ có khối lệnh sau if sẽ được thực hiện. Nếu giá trị điều kiện if else nào là True thì chỉ có khối lệnh sau else if đó sẽ được thực hiện… Nếu tất cả điều kiện của if và else if là False thì chỉ có khối lệnh sau else sẽ được thực hiện.

if_else_if_statement_diagram.png

Cú pháp:

if (condition1) {  
    // khối lệnh này được thực thi 
    // nếu condition1 là true  
} else if (condition2) {  
    // khối lệnh này được thực thi 
    // nếu condition2 là true  
}  else if (condition3) {  
    // khối lệnh này được thực thi 
    // nếu condition3 là true  
}  
...  
else {  
    // khối lệnh này được thực thi 
    // nếu tất cả những điều kiện trên là false                 
}

Ví dụ:

public class MyClass {

  public static void main(String[] args) {
    int time = 22;
    if (time < 10) {
      System.out.println("Good morning.");
    } else if (time < 20) {
      System.out.println("Good day.");
    }  else {
      System.out.println("Good evening.");
    }
  }
}

Kết quả:

Good evening. 

Java Short If-else statement - Cấu trúc If-else rút gọn trong Java

Câu lệnh Short If-else được sử dụng để rút gọn lệnh if-else, giúp chương trình ngắn gọn hơn.

if_statement_flow_chart_diagram.png

Cú pháp:

variable = (condition) ? expressionTrue :  expressionFalse;

Ví dụ:

Thay vì sử dụng if-else như ví dụ dưới đây:

public class MyClass {

    public static void main(String[] args) {
        int time = 20;
        if (time < 18) {
            System.out.println("Good day.");
        } else {
            System.out.println("Good evening.");
        }
    }
}

Có thể viết lại ngắn gọn như sau mà vẫn cho kết quả đúng:

public class MyClass {

    public static void main(String[] args) {
        int time = 20;
        String result;
        result = (time < 18) ? "Good day." : "Good evening.";
        System.out.println(result);
    }
}

Java Switch-case statement - Cấu trúc Switch-case trong Java

Câu lệnh switch-case có thể được xem như một dạng khác của câu lệnh if-else. Nó được sử dụng trong tình huống một biểu thức cho ra nhiều kết quả. Việc sử dụng câu lệnh switch-case cho phép việc lập trình dễ dàng và đơn giản hơn.

Cú pháp:

switch (expression)
{
	case 'value':
		action 1 statement;
		break;
	case 'value':
		action 2 statement;
		break;
	:
	:
	case 'valueN': 
		actionN statement (s);
		break;
	default:
		action default;
}

Trong đó:

Ví dụ:

Đoạn chương trình sau xác định giá trị trong một biến nguyên và hiển thị ngày trong tuần được thể hiện dưới dạng chuỗi. Để kiểm tra các giá trị nằm trong khoảng 0 đến 6, chương trình sẽ thông báo lỗi nếu nằm ngoài phạm vi trên.

class SwitchDemo {
    public static void main(String agrs[]) {
        int day = 4;
        switch (day) {
            case 0:
                system.out.println("Sunday");
                break;
            case 1:
                System.out.println("Monday");
                break;
            case 2:
                System.out.println("Tuesday");
                break;
            case 3:
                System.out.println("Wednesday");
                break;
            case 4:
                System.out.println("Thursday");
                break;
            case 5:
                System.out.println("Friday");
                break;
            case 6:
                System.out.println("Satuday");
                break;
            case 7:
                System.out.println("Saturday");
                break;
            default:
                System.out.println("Invalid day of week");
        }
    }
}

Java While loop - Vòng lặp While trong Java

Vòng lặp while được sử dụng khi vòng lặp được thực hiện mãi cho đến khi điều kiện thực thi vẫn là True. Số lượng vòng lặp không đựơc xác định trước song nó sẽ phụ thuộc vào từng điều kiện.

while_loop_flow_chart_diagram.png

Cú pháp:

while(condition)
{
	action statement;
	:
	:
}

Trong đó:

Ví dụ 1:

Đoạn chương trình sau tính giai thừa của số 5.Giai thừa được tính như tích 5*4*3*2*1

class WhileDemo {
    public static void main(String args[]) {
        int a = 5, fact = 1;
        while (a. >= 1) {
            fact *= a;
            a--;
        }
        System.out.println("The Factorial of 5 is " + fact);
    }
}

Ở ví dụ trên, vòng lặp được thực thi cho đến khi điều kiện a>=1 là True. Biến a được khai báo bên ngoài vòng lặp và được gán giá trị là 5. Cuối mỗi vòng lặp, giá tri của a giảm đi 1. Sau năm vòng giá trị của a bằng 0. Điều kiện trả về giá trị False và vòng lặp kết thúc. Kết quả sẽ được hiển thị The factorial of 5 is 120

Ví dụ 2:

Đoạn chương trình sau hiển thi tổng của 5 số lẻ đầu tiên

class ForDemo {
    public static void main(String args[]) {
        int i = 1, sum = 0;
        for (i = 1; i <= 10; i += 2)
            sum += i;
        System.out.println("sum of first five old numbers is " + sum);
    }
}

Ở ví dụ trên, i và sum là hai biến được gán các giá trị đầu là 1 và 0 tương ứng. Điều kiện được kiểm tra và khi nó còn nhận giá trị True, câu lệnh tác động trong vòng lặp được thực hiện. Tiếp theo giá trị của i được tăng lên 2 để tạo ra số lẻ tiếp theo. Một lần nữa, điều kiện lại được kiểm tra và câu lệnh tác động lại được thực hiện. Sau năm vòng, i tăng lên 11, điều kiện trả về giá trị False và vòng lặp kết thúc. Thông báo: Sum of first five odd numbers is 25 được hiển thị.

Java Do-while loop - Vòng lặp Do-while trong Java

Vòng lặp do-while trong java được sử dụng để lặp một phần của chương trình một vài lần. Tương tự như vòng lặp while, ngoại trừ do-while thực hiện lệnh ít nhất một lần ngay cả khi điều kiện là False.

do_while_loop_flowchart_diagram.png

Cú pháp:

do {  
    // Khối lệnh được thực thi
} while(condition);

Ví dụ:

Ví dụ sau tính tổng của 5 số tự nhiên đầu tiên dùng cấu trúc do-while

public class DoWhileExample1 {
    public static void main(String[] args) {
        int a = 1, sum = 0;
        do {
            sum += a;
            a++;
        } while (a <= 5);
        System.out.println("Sum of 1 to 5  is " + sum);
    }
}

Java For loop - Vòng lặp For trong Java

Vòng lặp for trong java được sử dụng để lặp một phần của chương trình nhiều lần. Nếu số lần lặp là cố định thì vòng lặp for được khuyến khích sử dụng, còn nếu số lần lặp không cố định thì nên sử dụng vòng lặp while hoặc do while.

for_loop_flow_chart_diagram.png

1. For loop basic

Cú pháp:

for (statement 1; statement 2; statement 3) {
  // code block to be executed
}

Trong đó:

Ví dụ:

public class MyClass {
  public static void main(String[] args) {
    for (int i = 0; i < 5; i++) {
      System.out.println(i);
    }  
  }
}
2. For-each loop

Vòng lặp for-each được sử dụng để lặp mảng (array) hoặc tập hợp (collection) trong java. Bạn có thể sử dụng nó dễ dàng, dễ hơn cả vòng lặp for đơn giản. Bởi vì bạn không cần phải tăng hay giảm giá trị của biến rồi check điều kiện, bạn chỉ cần sử dụng ký hiệu hai chấm ":"

Cú pháp:

for (type variableName : arrayName) {
  // code block to be executed
}

Ví dụ:

public class MyClass {

  public static void main(String[] args) {
    String[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
    for (String i : cars) {
      System.out.println(i);
    }    
  }
}

Java Break statement - Lệnh Break trong Java

Từ khóa break trong java được sử dụng để dừng và thoát thực thi lệnh trong vòng lặp (for, while, do-while) hoặc trong mệnh đề switch tại điều kiện đã được chỉ định. Đối với vòng lặp bên trong vòng lặp khác, thì nó chỉ dừng vòng lặp bên trong đó.

break_statement_flowchart_diagram.png

Cú pháp:

break; 

Ví dụ:

public class MyClass {

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i == 4) {
                break;
            }
            System.out.println(i);
        }
    }
}

Kết quả:

0
1
2
3 

Java Continue statement - Lệnh Continue trong Java

Từ khóa continue trong java được sử dụng để tiếp tục vòng lặp tại điều kiện đã được xác định, và khối lệnh phía sau từ khóa continue sẽ không được thực thi. Đối với vòng lặp bên trong một vòng lặp khác, continue chỉ có tác dụng với vòng lặp bên trong đó.

continue_statement_flowchart_diagram.png

Cú pháp:

continue;

Ví dụ:

public class MyClass {

    public static void main(String[] args) {
        for (int i = 0; i < 10; i++) {
            if (i == 4) {
                continue;
            }
            System.out.println(i);
        }
    }
}

Kết quả:

0
1
2
3
5
6
7
8
9 

Java Exceptions - Ngoại lệ trong Java

1. Giới thiệu

Exception là một lỗi đặc biệt. Lỗi này xuất hiện vào lúc thực thi chương trình. Các trạng thái không bình thường xảy ra trong khi thi hành chương trình tạo ra các exception. Những trạng thái này không được biết trước trong khi ta đang xây dựng chương trình. Nếu bạn không  phân phối các trạng thái này thì exception có thể bị kết thúc đột ngột. Ví dụ, việc chia cho 0 sẽ tạo một lỗi trong chương trình. Ngôn ngữ Java cung cấp bộ máy dùng để xử lý ngoại lệ rất tuyệt vời. Việc xử lý này làm hạn chế tối đa trường hợp hệ thống bị phá vỡ (crash) hay hệ thống bị ngắt đột ngột. Tính năng này làm cho Java là một ngôn ngữ lập trình mạnh.

2. Mục đích của việc xử lý ngoại lệ

Một chương trình nên có cơ chế xử lý ngoại lệ thích hợp. Nếu không, chương trình sẽ bị ngắt khi một exception xảy ra. Trong trường hợp đó, tất cả các nguồn tài nguyên mà hệ thống trước kia phân phối sẽ được di dời trong cùng trạng thái. Điều này gây lãng phí tài nguyên. Để tránh trường hợp này, tất cả các nguồn tài nguyên mà hệ thống phân phối nên được thu hồi lại. Tiến trình này đòi hỏi cơ chế xử lý ngoại lệ thích hợp.

Cho ví dụ, xét thao tác nhập xuất (I/O) trong một tập tin. Nếu việc chuyển đổi kiểu dữ liệu không thực hiện đúng, một ngoại lệ sẽ xảy ra và chương trình bị hủy mà không đóng lại tập tin. Lúc đó tập tin dễ bị hư hại và các nguồn tài nguyên được cấp phát cho tập tin không được thu hồi lại cho hệ thống.

3. Xử lý ngoại lệ

Khi một ngoại lệ xảy ra, đối tượng tương ứng với ngoại lệ đó được tạo ra. Đối tượng này sau đó được truyền cho phương thức là nơi mà ngoại lệ xảy ra. Đối tượng này chứa thông tin chi tiết về ngoại lệ. Thông tin này có thể được nhận về và được xử lý. Các môi trường runtime như 'IllegalAccessException', 'EmptyStackException' v.v… có thể chặn được các ngoại lệ. Đoạn mã trong chương trình đôi khi có thể tạo ra các ngoại lệ. Lớp 'throwable' được Java cung cấp là lớp trên nhất của lớp Exception, lớp này là lớp cha của các ngoại lệ khác nhau.

4. Hệ thống cấp bậc của các lớp ngoại lệ trong Java 

ExceptionHierarchy.png

5. Xử lý ngoại lệ

Trong Java, mô hình xử lý ngoại lệ kiểm tra việc xử lý những hiệu ứng lề (lỗi), được biết đến là mô hình ‘catch và throw’. Trong mô hình này, khi một lỗi xảy ra, một ngoại lệ sẽ bị chặn và được đưa vào trong một khối. Người lập trình viên nên xét các trạng thái ngoại lệ độc lập nhau từ việc điều khiển thông thường trong chương trình. Các ngoại lệ phải được bắt giữ  nếu không chương trình sẽ bị ngắt.

Ngôn ngữ Java cung cấp 5 từ khoá sau để xử lý các ngoại lệ:

6. Một số class ngoại lệ

Ngoại lệ

Mô tả

RuntimeException

Lớp cơ sở cho nhiều ngoại lệ java.lang

ArthmeticException

Trạng thái lỗi về số, ví dụ như ‘chia cho 0’

IllegalAccessException

Lớp không thể truy cập

IllegalArgumentException

Phương thức nhận một đối số không hợp lệ

ArrayIndexOutOfBoundsExeption

Kích thước của mảng lớn hơn 0 hay lớn hơn kích thước thật sự của mảng

NullPointerException

Khi muốn truy cập đối tượng null

SecurityException

Việc thiết lập cơ chế bảo mật không được hoạt động

ClassNotFoundException

Không thể nạp lớp yêu cầu

NumberFormatException

Việc chuyển đối không thành công từ chuỗi sang số thực

AWTException

Ngoại lệ về AWT

IOException

Lớp cha của các ngoại lệ I/O

FileNotFoundException

Không thể định vị tập tin

EOFException

Kết thúc một tập tin

NoSuchMethodException

Phương thức yêu cầu không tồn tại

InterruptedException

Khi một luồng bị ngắt

Java Try-catch exception - Khối Try-catch trong Java

Khối try-catch được sử dụng để thi hành mô hình catchthrow của việc xử lý ngoại lệ. Khối try chứa một bộ các lệnh có thể thi hành được. Các ngoại lệ có thể bị chặn khi thi hành những câu lệnh này. Phương thức dùng để chặn ngoại lệ có thể được khai báo trong khối try. Một hay nhiều khối catch có thể theo sau khối try. Các khối catch này bắt các ngoại lệ bị chặn trong khối try.

Cú pháp:

try {
    //  Block of code to try
}
catch(Exception e) {
    //  Block of code to handle errors
}

Ví dụ:

- Chương trình thông thường không sử dụng try-catch:

public class MyClass {

    public static void main(String[] args) {
        int[] myNumbers = {
            1,
            2,
            3
        };
        System.out.println(myNumbers[10]); // error!
    }
}

Kết quả lỗi:

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
        at MyClass.main(MyClass.java:4) 

- Chương trình sử dụng try-catch:

public class MyClass {

    public static void main(String[] args) {
        try {
            int[] myNumbers = {
                1,
                2,
                3
            };
            System.out.println(myNumbers[10]);
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        }
    }
}

Kết quả:

Something went wrong.

Java Multiple-catch block exception - Khối Multi-catch trong Java

Các khối chứa nhiều catch xử lý các kiểu ngoại lệ khác nhau một cách độc lập.

Khi sử dụng các try lồng nhau, khối try bên trong được thi hành đầu tiên. Bất kỳ ngoại lệ nào bị chặn trong khối try sẽ bị bắt giữ trong các khối catch theo sau. Nếu  khối ‘catch’ thích hợp không được tìm thấy thì các khối catch của các khối try bên ngoài sẽ được xem xét. Nếu không, Java Runtime Environment xử lý các ngoại lệ.

Cú pháp:

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}

Ví dụ 1:

public class TestMultipleCatchBlock {

    public static void main(String args[]) {
        try {
            int a[] = new int[5];
            a[5] = 30 / 0;
        } catch (ArithmeticException e) {
            System.out.println("task1 is completed");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("task 2 completed");
        } catch (Exception e) {
            System.out.println("common task completed");
        }

        System.out.println("rest of the code...");
    }
}

Kết quả:

task1 is completed
rest of the code...

Ví dụ 2:

public class TestMultipleCatchBlock1 {

    public static void main(String args[]) {
        try {
            int a[] = new int[5];
            a[5] = 30 / 0;
        } catch (Exception e) {
            System.out.println("common task completed");
        } catch (ArithmeticException e) {
            System.out.println("task1 is completed");
        } catch (ArrayIndexOutOfBoundsException e) {
            System.out.println("task2 is completed");
        }
        System.out.println("rest of the code...");
    }
}

Kết quả:

Compile-time error

Chương trình trên bị lỗi tại compile-time là vì khi có ngoại lệ xảy ra thì các khối lệnh catch (ArithmeticException e) và catch (ArrayIndexOutOfBoundsException e) không bao giờ được thực thi, do khối catch (Exception e) đã bắt tất cả các ngoại lệ rồi.

Java Finally block exception - Khối Finally trong Java

Khi một ngoại lệ xuất hiện, phương thức đang được thực thi có thể bị dừng mà không được thi hành toàn vẹn. Nếu điều này xảy ra, thì các đoạn mã (ví dụ như đoạn mã với chức năng thu hồi tài nguyên có các lệnh đóng lại tập tin khai báo cuối phương thức) sẽ không bao giờ được gọi. Java cung cấp khối finally để giải quyết việc này. Khối finally thực hiện tất cả các việc thu dọn khi một ngoại lệ xảy ra. Khối này được sử dụng kết hợp với khối try, khối finally chứa các câu lệnh thu hồi tài nguyên về cho hệ thống hay lệnh in ra các câu thông báo.

Các lệnh này bao gồm:

Cú pháp:

try {
   // Protected code
} catch (ExceptionType1 e1) {
   // Catch block
} catch (ExceptionType2 e2) {
   // Catch block
} catch (ExceptionType3 e3) {
   // Catch block
}finally {
   // The finally block always executes.
}

Ví dụ:

public class MyClass {

    public static void main(String[] args) {
        try {
            int[] myNumbers = {
                1,
                2,
                3
            };
            System.out.println(myNumbers[10]);
        } catch (Exception e) {
            System.out.println("Something went wrong.");
        } finally {
            System.out.println("The 'try catch' is finished.");
        }
    }
}

Kết quả:

Something went wrong.
The 'try catch' is finished. 

Java Throw exception - Ném ngoại lệ trong Java

Các ngoại lệ bị chặn với sự trợ giúp của từ khoá throw. Từ khóa throw chỉ ra một ngoại lệ vừa xảy ra. Toán tử của throw là một đối tượng của lớp, lớp này được dẫn xuất từ Throwable.

Tóm lại, mục đích của thow để ném ngoại lệ cụ thể.

Cú pháp:

throw exception;

Ví dụ:

public class MyClass {

    static void checkAge(int age) {
        if (age < 18) {
            throw new ArithmeticException("Access denied - You must be at least 18 years old.");
        } else {
            System.out.println("Access granted - You are old enough!");
        }
    }

    public static void main(String[] args) {
        checkAge(15); // Set age to 15 (which is below 18...)
    }
}

Kết quả:

Exception in thread "main" java.lang.ArithmeticException: Access denied - You must be at least 18 years old.
        at MyClass.checkAge(MyClass.java:4)
        at MyClass.main(MyClass.java:12) 

Java Throws exception - Khai bao ngoại lệ trong Java

Từ khóa throws trong java được sử dụng để khai báo một ngoại lệ. Nó thể hiện thông tin cho lập trình viên rằng có thể xảy ra một ngoại lệ, vì vậy nó là tốt hơn cho các lập trình viên để cung cấp các mã xử lý ngoại lệ để duy trì luồng bình thường của chương trình.

Exception Handling chủ yếu được sử dụng để xử lý ngoại lệ checked. Nếu xảy ra bất kỳ ngoại lệ unchecked như NullPointerException, đó là lỗi của lập trình viên mà anh ta không thực hiện kiểm tra trước khi code được sử dụng.

Mục đích của throws:

Cú pháp:

ReturnType methodName() throws ExceptionClassName {  
    // method code
}

Ví dụ:

import java.io.IOException;

class Testthrows1 {

    void m() throws IOException {
        throw new IOException("device error"); //checked exception  
    }
    void n() throws IOException {
        m();
    }
    void p() {
        try {
            n();
        } catch (Exception e) {
            System.out.println("exception handled");
        }
    }
    public static void main(String args[]) {
        Testthrows1 obj = new Testthrows1();
        obj.p();
        System.out.println("normal flow...");
    }
}

Kết quả:

exception handled
normal flow...

Sự khác nhau giữa Throw và Throws trong java

Có một số điểm khác nhau giữa từ khóa throwthrows trong java được mô tả trong bảng dưới đây:

No. throw throws
1) Từ khóa throw trong java được sử dụng để ném ra một ngoại lệ rõ ràng. Từ khóa throws trong java được sử dụng để khai báo một ngoại lệ.
2) Ngoại lệ checked không được truyền ra nếu chỉ sử dụng từ khóa throw. Ngoại lệ checked được truyền ra ngay cả khi chỉ sử dụng từ khóa throws.
3) Sau throw là một instance. Sau throws là một hoặc nhiều class.
4) Throw được sử dụng trong phương thức. Throws được khai báo ngay sau dấu đóng ngoặc đơn của phương thức.
5) Bạn không thể throw nhiều exceptions. Bạn có thể khai báo nhiều exceptions, Ví dụ:
public void method()throws IOException,SQLException.

Java User-defined exception - Tự định nghĩa ngoại lệ trong Java

Lớp Exception thực thi giao diện Throwable và cung cấp các tính năng hữu dụng để phân phối các ngoại lệ. Ưu điểm của nó là tạo các lớp ngoại lệ được định nghĩa bởi người dùng. Để làm điều này, một lớp con của lớp Exception được tạo ra. Ưu điểm của lớp con là một kiểu ngoại lệ mới có thể bị bắt giữ độc lập từ các loại Throwable khác.

Nếu bạn tạo ngoại lệ riêng của mình được biết đến như ngoại lệ tùy chỉnh (exception tùy chỉnh) hoặc ngoại lệ do người dùng định nghĩa. Các ngoại lệ tùy chỉnh trong Java được sử dụng để tùy chỉnh ngoại lệ theo nhu cầu của người dùng.

Cú pháp:

class MyException extends Exception {
}

Ví dụ:

Chương trình sau minh họa ngoại lệ được định nghĩa bởi người dùng ArraySizeException

public class ThrowDemo {
    int size, array[];
    ThrowDemo(int s) {
        size = s;
        try {
            checkSize();
        } catch (ArraySizeException e) {
            System.out.println(e);
        }
    }
    void checkSize() throws ArraySizeException {
        if (size < 0)
            throw new ArraySizeException();
        else
            System.out.println("The array size is ok.");
        array = new int[3];
        for (int i = 0; i < 3; i++)
            array[i] = i + 1;
    }
    public static void main(String arg[]) {
        new ThrowDemo(-1);
    }
}
class ArraySizeException extends NegativeArraySizeException {
    ArraySizeException() // constructor
    {
        super("You have passed an  illegal array size");
    }
}

Kết quả:

$javac ThrowDemo.java
$java -Xmx128M -Xms16M ThrowDemo
ArraySizeException: You have passed an  illegal array size

Java Constructor - Phương thức khởi tạo trong Java

Contructor thật ra là một loại phương thức đặc biệt của lớp. Constructor dùng gọi tự động khi khởi tạo một thể hiện của lớp, có thể dùng để khởi gán những giá trị măc định. Các constructor không có giá trị trả về, và có thể có tham số hoặc không có tham số.

Constructor phải có cùng tên với lớp và được gọi đến dùng từ khóa new.

Nếu một lớp không có constructor thì java sẽ cung cấp cho lớp một constructor mặc định (default constructor). Những thuộc tính, biến của lớp sẽ được khởi tạo bởi các giá trị mặc định (số: thường là giá trị 0, kiểu luận lý là giá trị false, kiểu đối tượng giá trị null…).

Lưu ý: thông thường để an toàn, dễ kiểm soát và làm chủ mã nguồn chương trình chúng ta nên khai báo một constructor cho lớp.

Ví dụ:

public class xemay {
    // …
    public xemay() {}
    public xemay(String s_nhasx, String s_model,
        f_chiphisx, int i_thoigiansx, int i_so); {
        nhasx = s_nhasx;
        model = s_model;
        chiphisx = f_chiphisx;
        thoigiansx = i_thoigiansx;
        so = i_so;
        // hoặc
        // this.nhasx = s_nhasx;
        // this.model = s_model;
        // this.chiphisx = f_chiphisx;
        // this.thoigiansx = i_thoigiansx;
        // this.so = i_so;
    }
}

Java Inner class - Lớp nội trong Java

Lớp nội là lớp được khai báo bên trong 1 lớp khác. Lớp nội thể hiện tính đóng gói cao và có thể truy xuất trực tiếp biến của lớp cha.

Ví dụ:

public class A {
    // …
    int < field_1 >
        static class B {
            // …
            int < field_2 >
                public B(int par_1) {
                    field_2 = par_1 + field_1;
                }
        }
}

Trong ví dụ trên thì chương trình dịch sẽ tạo ra hai lớp với hai files khác nhau: A.classB.class

Java Final class - Lớp "vô sinh" trong Java

Lớp không thể có lớp dẫn xuất từ nó (không có lớp con) gọi là lớp "vô sinh", hay nói cách khác không thể kế thừa được từ một lớp "vô sinh". Lớp "vô sinh" dùng để hạn chế, ngăn ngừa các lớp khác dẫn xuất từ nó.

Để khai báo một lớp là lớp "vô sinh", chúng ta dùng từ khóa final class.

Tất cả các phương thức của lớp vô sinh đều vô sinh, nhưng các thuộc tính của lớp vô sinh thì có thể không vô sinh.

Ví dụ:

public final class A {
    public final int x;
    private int y;
    public final void method_1() {
        // …
    }
    public final void method_2() {
        // …
    }
}

 

Java Finalize method - Phương thức finalize trong Java

Trong Java không có kiểu dữ liệu con trỏ như trong C, người lập trình không cần phải quá bận tâm về việc cấp phát và giải phóng vùng nhớ, sẽ có một trình dọn dẹp hệ thống đảm trách việc này. Trình dọn dẹp hệ thống sẽ dọn dẹp vùng nhớ cấp phát cho các đối tượng trước khi hủy một đối tượng.

Phương thức finalize() là một phương thức đặc biệt được cài đặt sẵn cho các lớp. Trình dọn dẹp hệ thống sẽ gọi phương thức này trước khi hủy một đối tượng. Vì vậy việc cài đặt một số thao tác giải phóng, dọn dẹp vùng nhớ đã cấp phát cho các đối tượng dữ liệu trong phương thức finalize() sẽ giúp cho người lập trình chủ động kiểm soát tốt quá trình hủy đối tượng thay vị giao cho trình dọn dẹp hệ thống tự động. Đồng thời việc cài đặt trong phương thức finalize() sẽ giúp cho bộ nhớ được giải phóng tốt hơn, góp phần cải tiến tốc độ chương trình.

Ví dụ:

class A {
    // Khai báo các thuộc tính
    public void method_1() {
        // …
    }
    protected void finalize() {
        // Có thể dùng để đóng tất cả các kết nối
        // vào cơ sở dữ liệu trước khi hủy đối tượng.
        // …
    }
}

Java Streams I/O - Luồng I/O trong Java

Tất cả những hoạt động nhập/xuất dữ liệu (nhập dữ liệu từ bàn phím, lấy dữ liệu từ mạng về, ghi dữ liệu ra đĩa, xuất dữ liệu ra màn hình, máy in...) đều được quy về một khái niệm gọi là luồng (stream).

java-streams.png

Luồng là nơi có thể "sản xuất" và "tiêu thụ" thông tin. Luồng thường được hệ thống xuất nhập trong java gắn kết với một thiết bị vật lý. Tất cả các luồng đều có chung một nguyên tắc hoạt động ngay cả khi chúng được gắn kết với các thiết bị vật lý khác nhau. Vì vậy cùng một lớp, phương thức xuất nhập có thể dùng chung cho các thiết bị vật lý khác nhau. Chẳng hạn cùng một phương thức có thể dùng để ghi dữ liệu ra console, đồng thời cũng có thể dùng để ghi dữ liệu xuống một file trên đĩa. Java hiện thực luồng bằng tập hợp các lớp phân cấp trong gói java.io.

Java định nghĩa hai kiểu luồng: byte và ký tự (phiên bản gốc chỉ định nghĩa kiểu luồng byte, và sau đó luồng ký tự được thêm vào trong các phiên bản về sau).

Luồng byte (hay luồng dựa trên byte) hỗ trợ việc xuất nhập dữ liệu trên byte, thường được dùng khi đọc ghi dữ liệu nhị phân.

Luồng ký tự được thiết kế hỗ trợ việc xuất nhập dữ liệu kiểu ký tự (Unicode). Trong một vài trường hợp luồng ký tự sử dụng hiệu quả hơn luồng byte, nhưng ở mức hệ thống thì tất cả những xuất nhập đều phải qui về byte. Luồng ký tự hỗ trợ hiệu quả chỉ đối với việc quản lý, xử lý các ký tự

Java Byte I/O - Luồng Byte trong Java

Các luồng byte được định nghĩa dùng hai lớp phân cấp. Mức trên cùng là hai lớp trừu tượng InputStreamOutputStream:

java-streams.png

Các lớp con dẫn xuất từ hai lớp InputStream và OutputStream sẽ hỗ trợ chi tiết tương ứng với việc đọc ghi dữ liệu trên những thiết bị khác nhau. Đừng choáng ngợp với hàng loạt rất nhiều các lớp khác nhau. Đừng quá lo lắng, mỗi khi bạn nắm vững, sử dụng thành thạo một luồng byte nào đó thì bạn dễ dàng làm việc với những luồng còn lại.

#
Lớp luồng byte  Ý nghĩa
1 BufferedInputStream  Buffered input stream
2 BufferedOutputStream  Buffered output stream
3 ByteArrayInputStream  Input stream đọc dữ liệu từ một mảng byte
4 ByteArrayOutputStream  Output stream ghi dữ liệu đến một mảng byte
5 DataInputStream  Luồng nhập có những phương thức đọc những kiểu dữ liệu chuẩn trong java
6 DataOutputStream  Luồng xuất có những phương thức ghi những kiểu dữ liệu chuẩn trong java
7 FileInputStream  Luồng nhập cho phép đọc dữ liệu từ file
8 FileOutputStream  Luồng xuất cho phép ghi dữ liệu xuống file
9 FilterInputStream  Hiện thực lớp trừu tượng InputStream
10 FilterOutputStream  Hiện thực lớp trừu tượng OutputStream
11 InputStream  Lớp trừu tượng, là lớp cha của tất cả các lớp luồng nhập kiểu Byte
12 OutputStream  Lớp trừu tượng, là lớp cha của tất cả các lớp xuất nhập kiểu Byte
13 PipedInputStream  Luồng nhập byte kiểu ống (piped) thường phải được gắn với một luồng xuất kiểu ống.
14 PipedOutputStream  Luồng nhập byte kiểu ống (piped) thường phải được gắn với một luồng nhập kiểu ống để tạo nên một kết nối trao đổi dữ liệu kiểu ống.
15 PrintStream  Luồng xuất có chứa phương thức print() và println()
16 PushbackInputStream  Là một luồng nhập kiểu Byte mà hỗ trợ thao tác trả lại (push back) và phục hồi thao tác đọc một byte (unread)
17 RandomAccessFile  Hỗ trợ các thao tác đọc, ghi đối với file truy cập ngẫu nhiên.
18 SequenceInputStream  Là một luồng nhập được tạo nên bằng cách nối kết logic các luồng nhập khác.

Java Character I/O - Luồng ký tự trong Java

Các luồng ký tự được định nghĩa dùng hai lớp phân cấp. Mức trên cùng là hai lớp trừu tượng Reader và Writer:

java-streams.png

# Lớp luồng ký tự  Ý nghĩa
1 BufferedReader  Luồng nhập ký tự đọc dữ liệu vào một vùng đệm.
2 BufferedWriter  Luồng xuất ký tự ghi dữ liệu tới một vùng đệm.
3 CharArrayReader  Luồng nhập đọc dữ liệu từ một mảng ký tự
4 CharArrayWriter  Luồng xuất ghi dữ liệu tời một mảng ký tự
5 FileReader  Luồng nhập ký tự đọc dữ liệu từ file
6 FileWriter  Luồng xuất ký tự ghi dữ liệu đến file
7 FilterReader  Lớp đọc dữ liệu trung gian (lớp trừu tượng)
8 FilterWriter  Lớp xuất trung gian trừu tượng
9 InputStreamReader  Luồng nhập chuyển bytes thành các ký tự
10 LineNumberReader  Luồng nhập đếm dòng
11 OutputStreamWriter  Luồng xuất chuyển những ký tự thành các bytes
12 PipedReader  Luồng đọc dữ liệu bằng cơ chế đường ống
13 PipedWriter  Luồng ghi dữ liệu bằng cơ chế đường ống
14 PrintWriter  Luồng ghi văn bản ra thiết bị xuất (chứa phương thức print() và println())
15 PushbackReader  Luồng nhập cho phép đọc và khôi phục lại dữ liệu
16 Reader  Lớp nhập dữ liệu trừu tượng
17 StringReader  Luồng nhập đọc dữ liệu từ chuỗi
18 StringWriter  Luồng xuất ghi dữ liệu ra chuỗi
19 Writer  Lớp ghi dữ liệu trừu tượng

Java this keyword - Biến this trong Java

Biến this là một biến ẩn tồn tại trong tất cả các lớp trong ngông ngữ java. Một class trong Java luôn tồn tại một biến this, biến this được sử dụng trong khi chạy và tham khảo đến bản thân lớp chứa nó.

Ví dụ:

< tiền tố > class A { 
  < tiền tố > int < field_1 > ; 
  < tiền tố > String < field_2 > ;
  // Contructor của lớp A
  public A(int par_1, String par_2) {
    this.field_1 = par_1;
    this.field_2 = par_2;
  } 
  
  < tiền tố > <kiểu trảvề > <method_1 > () {
    // ... 
  }
  
  < tiền tố > <kiểu trảvề > <method_2 > () {
      this.method_1()
      // ... 
  }
 }