1. Ép kiểu dữ liệu trong Java là gì?

Ép kiểu (Type Casting) dữ liệu trong Java là quá trình chuyển đổi kiểu dữ liệu trong Java. Nó thường được sử dụng trong trường hợp gán một giá trị vào một biến khi mà kiểu của biến và của giá trị lại hoàn toàn khác nhau. Chúng ta cần sử dụng đến thao tác ép kiểu khi chúng ta cần chuyển đổi kiểu dữ liệu của biến này sang kiểu dữ liệu khác để phục vụ cho một mục đích nào đó.

Ví dụ: ta thực hiện phép chia số nguyên 2 cho 4, nếu chúng ta không sử dụng đến ép kiểu thì kết quả của phép toán này sẽ trả về 0, như vậy thì yêu cầu của bài toán đã không còn đúng nữa.

Trong Java, có 13 kiểu ép đổi kiểu. Tuy nhiên, trong bài học này, chúng ta sẽ chỉ tập trung vào 2 loại chính đó là:

  • Ép kiểu mở rộng – Implicit Casting : Mở rộng Truyền (tự động) – chuyển đổi một loại nhỏ hơn thành một kích thước loại lớn hơn byte-> short-> char-> int-> long-> float->double
  • Ép kiểu hẹp – Explicit Casting : Thu hẹp Truyền (thủ công) – chuyển đổi loại lớn hơn sang loại kích thước nhỏ hơn double-> float-> long-> int-> char-> short->byte

Chúng ta không phải gán trực tiếp giá trị của số cho biến mà phải qua một bước trung gian nhằm thay đổi kiểu dữ liệu của số cho phù hợp với biến với các quy tắc ép kiểu rõ ràng. Và các toán tử sử dụng cho việc thay đổi (ép kiểu) này được gọi là toán tử ép kiểu dữ liệu trong Java.

2. Quy tắc ép kiểu dữ liệu trong Java

Java là ngôn ngữ lập trình cần quyết định kiểu của một biến khi tạo ra biến đó. Bởi vậy về cơ bản thì chúng ta không thể gán một giá trị khác kiểu với kiểu của biến đó khi khai báo. Ví dụ đơn giản như việc ta gán một số kiểu int vào một biến kiểu string thì một lỗi sẽ xảy ra.

String str;
str = 1;

Tuy nhiên với kiểu số, chúng ta lại có thể gán một số thuộc kiểu dữ liệu hẹp hơn, vào một biến có kiểu dữ liệu rộng hơn. Ví dụ, chúng ta có thể gán số thuộc kiểu int vào một biến thuộc kiểu long , vì kiểu long rộng hơn kiểu int , mà không xảy ra lỗi như sau:

double num; //biến num thuộc kiểu double
num = 100;  //số 100 thuộc kiểu int

Trong trường hợp này, số 100 thuộc kiểu int sẽ được tự động ép kiểu sang kiểu double , sau khi gán vào biến kiểu double . Và cách ép kiểu tự động không cần dùng tới toán tử như thế này được gọi là ép kiểu rộng hay còn gọi là ép kiểu không tường minh (Implicit Casting) trong Java. Và ngược lại, nếu chúng ta gán một số có kiểu dữ liệu rộng hơn kiểu dữ liệu của biến đem chứa nó, do kích thước của giá trị lớn hơn của biến, nên nếu không sử dụng tới các toán tử ép kiểu thì lỗi sẽ xảy ra.

Ví dụ, khi chúng ta cố gán một số kiểu double vào một biến kiểu int

int i;
i = 1.23;

Trong trường hợp này, kiểu dữ liệu sẽ không tự động thay đổi và chúng ta cần phải dùng tới toán tử ép kiểu. Và cách ép kiểu cần sử dụng tới toán tử ép kiểu như vậy được gọi là ép kiểu hẹp hay còn gọi là ép kiểu tường minh (Explicit Casting) trong Java.

3. Ép kiểu mở rộng trong Java

Trong ép kiểu mở rộng, Java tự động chuyển đổi một kiểu dữ liệu sang kiểu dữ liệu khác. Hay nó chính là việc khi chúng ta gán một giá trị có kiểu nhỏ hơn kiểu dữ liệu của một biến, thì giá trị đó sẽ được tự động ép kiểu, và chúng ta gọi phương pháp ép kiểu này là ép kiểu rộng hay còn gọi là ép kiểu không tường minh (Implicit Casting) trong Java.

Sơ đồ chuyển đổi như sau: byte → short → int → long → float → double

Ví dụ:

class Main {
  public static void main(String[] args) {
    int myInt = 9;
    double myDouble = myInt; // tự động chuyển int thành double

    System.out.println(myInt);
    System.out.println(myDouble);
  }
}

Kết quả

9
9.0

Lưu ý

Chúng ta không thể ép kiểu short sang kiểu charchar có phạm vi lớn hơn short vì kiểu short với phạm vi từ -32768 đến 32767 chứa số âm

Chúng ta không thể ép kiểu byte sang kiểu charchar có phạm vi lớn hơn byte vì kiểu byte với phạm vi từ -128 đến 128 có chứa cả số âm

Và với kiểu Boolean , trong Java chúng ta không thể ép kiểu tự động bất kỳ kiểu dữ liệu nào về Boolean được.

Một ví dụ khác về ép kiểu int về kiểu float :

class Main{
    public static void main(String[] args){
        float f = 10;
        double d = 1234L;

        System.out.println("f=:" + f);
        System.out.println("d=:" + d);
    }
}

Kết quả

f=:10.0
d=:1234.0

4. Ép kiểu hẹp trong Java

Trong ép kiểu thu hẹp , chúng ta ép đổi thủ công một kiểu dữ liệu này sang kiểu dữ liệu khác bằng cách sử dụng dấu ngoặc đơn. Nó hoàn toàn ngược lại với ép kiểu mở rộng. Khi chúng ta muốn gán một giá trị có phạm vi của kiểu dữ liệu lại lớn hơn phạm vi kiểu của biến chứa nó, nếu không sử dụng tới toán tử ép kiểu thì lỗi sẽ xảy ra. Ví dụ như khi chúng ta gán một số thuộc kiểu float cho một biến thuộc kiểu int chẳng hạn. Do chúng ta ép kiểu hẹp dần từ một dữ liệu lớn vào một cái hộp nhỏ hơn chứa nó, nên cách ép kiểu này được gọi là ép kiểu hẹp trong Java.

Sơ đồ chuyển đổi sẽ như sau : double → float → long → int → short → byte

Chúng ta sẽ sử dụng cú pháp sau : (data_type) variable

Trong đó :

  • data_type : Là kiểu dữ liệu mà bạn muốn ép về. Nó cần được đặt trong dấu ngoặc ()
  • variable : Là biến chứa dữ liệu bạn muốn ép.

Ví dụ:

class Main {
  public static void main(String[] args) {
    double myDouble = 9.78d;
    int myInt = (int) myDouble; // double -> int

    System.out.println(myDouble);
    System.out.println(myInt);
  }
}

Kết quả

9.78
9

Một ví dụ sử dụng cùng lúc 2 loại ép kiểu trên

class Main{
 
    public static void main(String[] args) {
        int height = 6;
        double mass = 220.23456;
         
        // ép kiểu mở rộng
        double result = height;
        System.out.println("Giá trị của biến result sau khi ép kiểu = " + result);  // 6.0
         
        // ép kiểu hẹp
        int massVal = (int) mass;
        System.out.println("Giá trị biến massValue sau khi ép kiểu = " + massVal);  // 220  
    }
 
}

Kết quả

Giá trị của biến result sau khi ép kiểu = 6.0

Giá trị biến massValue sau khi ép kiểu = 220