Xin chào! Khi tìm hiểu về JavaRush, bạn đã gặp các kiểu nguyên thủy nhiều lần. Dưới đây là danh sách ngắn những gì chúng ta biết về họ:
Tuy nhiên, ngoài giá trị, các loại còn khác nhau về kích thước bộ nhớ.
Loại này
- Chúng không phải là đối tượng và đại diện cho một giá trị được lưu trữ trong bộ nhớ
- Có một số loại kiểu nguyên thủy:
- Các số nguyên -
byte
,short
,int
,long
- Số dấu phẩy động (phân số) -
float
vàdouble
- Boolean -
boolean
- Tượng trưng (để biểu thị các chữ cái và số) -
char
- Các số nguyên -
- Mỗi người trong số họ có phạm vi giá trị riêng:
Kiểu nguyên thủy | Kích thước trong bộ nhớ | Phạm vi giá trị |
---|---|---|
byte | 8 bit | -128 đến 127 |
ngắn | 16bit | đến -32768 đến 32767 |
ký tự | 16bit | từ 0 đến 65536 |
int | 32 bit | từ -2147483648 đến 2147483647 |
dài | 64 bit | từ -9223372036854775808 đến 9223372036854775807 |
trôi nổi | 32 bit | từ (2 lũy thừa -149) đến ((2-2 lũy thừa -23)*2 lũy thừa 127) |
gấp đôi | 64 bit | từ (-2 lũy thừa 63) đến ((2 lũy thừa 63) - 1) |
boolean | 8 (khi được sử dụng trong mảng), 32 (khi được sử dụng trong không phải mảng) | đúng hay sai |
int
mất nhiều hơn byte
. A long
- hơn short
. Lượng bộ nhớ bị chiếm giữ bởi những con búp bê nguyên thủy có thể được so sánh với những con búp bê lồng nhau: Có không gian trống bên trong con búp bê lồng nhau. Búp bê làm tổ càng lớn thì càng có nhiều không gian. long
Chúng ta có thể dễ dàng đặt một cái nhỏ hơn vào bên trong một con búp bê làm tổ lớn int
. Nó vừa vặn một cách dễ dàng và bạn không cần phải làm gì thêm. Trong Java, khi làm việc với các kiểu nguyên thủy, điều này được gọi là chuyển đổi tự động. Theo một cách khác, nó được gọi là phần mở rộng. Đây là một ví dụ mở rộng đơn giản:
public class Main {
public static void main(String[] args) {
int bigNumber = 10000000;
byte littleNumber = 16;
bigNumber = littleNumber;
System.out.println(bigNumber);
}
}
Ở đây chúng ta gán giá trị byte
cho một biến int
. Nhiệm vụ đã thành công và không có bất kỳ vấn đề nào: giá trị được lưu trữ trong byte
chiếm ít không gian bộ nhớ hơn mức “vừa” trong int
. “Con búp bê làm tổ nhỏ” (giá trị byte
) dễ dàng phù hợp với “matryoshka lớn” (biến int
). Đó là một vấn đề khác khi bạn cố gắng làm điều ngược lại - đặt một giá trị lớn vào một biến không được thiết kế cho các kích thước đó. Về nguyên tắc, thủ thuật này sẽ không hoạt động với những con búp bê lồng nhau thực sự, nhưng trong Java, nó sẽ hoạt động, nhưng có nhiều sắc thái. Hãy thử đặt một giá trị int
vào một biến short
:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = bigNumber;//error!
System.out.println(bigNumber);
}
Lỗi! Trình biên dịch hiểu rằng bạn đang cố gắng làm điều gì đó không chuẩn và đặt một con búp bê matryoshka lớn ( int
) bên trong một con búp bê nhỏ ( short
). Lỗi biên dịch trong trường hợp này là cảnh báo từ trình biên dịch: “ Này, bạn có chắc chắn muốn làm điều này không? “Nếu bạn chắc chắn, hãy nói với trình biên dịch về điều đó: “ Mọi thứ đều ổn, tôi biết mình đang làm gì!” ” Quá trình này được gọi là chuyển đổi loại rõ ràng hoặc thu hẹp . Để thu hẹp, bạn cần chỉ rõ loại mà bạn muốn truyền giá trị của mình. Nói cách khác, hãy trả lời câu hỏi của người biên soạn: “ Chà, bạn muốn đặt con búp bê lớn này vào con búp bê nhỏ nào?” ” Trong trường hợp của chúng tôi, nó sẽ trông như thế này:
public static void main(String[] args) {
int bigNumber = 10000000;
short littleNumber = 1000;
littleNumber = (short) bigNumber;
System.out.println(littleNumber);
}
Chúng tôi đã chỉ ra rõ ràng rằng chúng tôi muốn khớp giá trị int
vào một biến short
và chịu trách nhiệm về nó. Trình biên dịch, nhìn thấy dấu hiệu rõ ràng về loại hẹp hơn, sẽ thực hiện chuyển đổi. Kết quả sẽ như thế nào? Đầu ra của bàn điều khiển: -27008 Hơi bất ngờ. Tại sao chính xác như thế này? Nó thực sự đơn giản. Chúng ta có giá trị ban đầu - 10000000 Nó được lưu trữ trong một biến int
chiếm 32 bit và ở dạng nhị phân, nó trông như thế này: Chúng ta ghi giá trị này vào biến short
, nhưng nó chỉ có thể lưu trữ 16 bit! Theo đó, chỉ 16 bit đầu tiên của số chúng ta sẽ được chuyển đến đó, phần còn lại sẽ bị loại bỏ. Kết quả là biến short
sẽ chứa giá trị , ở dạng thập phân chính xác bằng -27008. Đó là lý do tại sao trình biên dịch “yêu cầu xác nhận” ở dạng chuyển đổi rõ ràng sang một loại cụ thể. Thứ nhất, nó cho thấy rằng bạn chịu trách nhiệm về kết quả và thứ hai, nó cho trình biên dịch biết lượng không gian cần phân bổ khi truyền kiểu. Rốt cuộc, nếu trong ví dụ trước chúng ta đã chuyển int
sang type byte
, chứ không phải short
, thì chúng ta sẽ chỉ có 8 bit tùy ý sử dụng chứ không phải 16 và kết quả sẽ khác. Đối với các loại phân số ( float
và double
), việc thu hẹp xảy ra khác nhau. Nếu bạn cố gắng chuyển đổi một số như vậy thành kiểu số nguyên, phần phân số của nó sẽ bị loại bỏ.
public static void main(String[] args) {
double d = 2.7;
long x = (int) d;
System.out.println(x);
}
Đầu ra bảng điều khiển: 2
ký tự kiểu dữ liệu
Bạn đã biết rằng kiểu char được dùng để hiển thị các ký tự riêng lẻ.public static void main(String[] args) {
char c = '!';
char z = 'z';
char i = '8';
}
Nhưng nó có một số tính năng quan trọng cần phải hiểu. Hãy nhìn lại bảng với các phạm vi giá trị:
Kiểu nguyên thủy | Kích thước trong bộ nhớ | Phạm vi giá trị |
---|---|---|
byte | 8 bit | -128 đến 127 |
ngắn | 16bit | -32768 đến 32767 |
ký tự | 16bit | từ 0 đến 65536 |
int | 32 bit | từ -2147483648 đến 2147483647 |
dài | 64 bit | từ -9223372036854775808 đến 9223372036854775807 |
trôi nổi | 32 bit | từ (2 lũy thừa -149) đến ((2-2 lũy thừa -23)*2 lũy thừa 127) |
gấp đôi | 64 bit | từ (-2 lũy thừa 63) đến ((2 lũy thừa 63)-1) |
boolean | 8 (khi được sử dụng trong mảng), 32 (khi được sử dụng trong không phải mảng) | đúng hay sai |
char
có phạm vi số từ 0 đến 65536. Nhưng điều này có nghĩa là gì? Suy cho cùng, char
đây không chỉ là những con số mà còn cả những chữ cái, dấu chấm câu... Thực tế là các giá trị char
được lưu trữ trong Java ở định dạng Unicode. Chúng ta đã gặp Unicode ở một trong những bài giảng trước. Bạn có thể nhớ rằng Unicode là một tiêu chuẩn mã hóa ký tự bao gồm các ký tự từ hầu hết các ngôn ngữ viết trên thế giới. Nói cách khác, đây là danh sách các mã đặc biệt, trong đó có mã cho hầu hết mọi ký tự từ bất kỳ ngôn ngữ nào. Bảng Unicode chung rất lớn và tất nhiên không cần phải học thuộc lòng. Ví dụ, đây là một phần của nó: Điều chính là phải hiểu nguyên tắc lưu trữ các giá trị char
và hãy nhớ rằng biết mã của một ký hiệu cụ thể, bạn luôn có thể lấy nó trong chương trình. Hãy thử điều này với một số số ngẫu nhiên:
public static void main(String[] args) {
int x = 32816;
char c = (char) x ;
System.out.println(c);
}
Đầu ra của bảng điều khiển: 耰 Đây là định dạng mà các ký tự được lưu trữ trong Java char
. Mỗi ký tự tương ứng với một số - mã số 16 bit hoặc hai byte. Unicode 32816 tương ứng với ký tự 耰. Hãy chú ý đến thời điểm này. Trong ví dụ này chúng tôi đã sử dụng biến int
. Nó chiếm 32 bit bộ nhớ , trong khi char
16 bit . Ở đây chúng tôi chọn vì số chúng tôi cần, 32816, nằm ngoài phạm vi . Mặc dù kích thước , giống như short, là 16 bit, nhưng không có số âm trong phạm vi, do đó phạm vi "dương" lớn gấp đôi (65536 thay vì 32767 ). Chúng ta có thể sử dụng , miễn là mã của chúng ta nằm trong phạm vi 65536. Nhưng nếu chúng ta tạo một số , nó sẽ chiếm hơn 16 bit. Và khi thu hẹp các loại: int
short
char
char
char
short
int
int >65536
char c = (char) x;
các bit thừa sẽ bị loại bỏ và kết quả sẽ khá bất ngờ.
Tính năng cộng char và số nguyên
Hãy xem ví dụ bất thường này:public class Main {
public static void main(String[] args) {
char c = '1';
int i = 1;
System.out.println(i+c);
}
}
Đầu ra của bàn điều khiển: 50 O_O Logic ở đâu? 1+1, 50 đến từ đâu?! Bạn đã biết rằng các giá trị char
được lưu trữ trong bộ nhớ dưới dạng các số trong phạm vi từ 0 đến 65536, đại diện cho Unicode của ký tự của chúng ta. Vì vậy, nó ở đây. Khi chúng tôi thực hiện phép cộng char
và một số loại số nguyên char
được chuyển đổi thành số tương ứng với nó trong Unicode. Khi trong mã của chúng tôi, chúng tôi đã thêm 1 và '1', ký hiệu '1' đã được chuyển đổi thành mã của nó, là 49 (bạn có thể kiểm tra nó trong bảng trên). Do đó, kết quả bằng 50. Chúng ta hãy một lần nữa lấy người bạn cũ -耰làm ví dụ và thử cộng nó với một số nào đó.
public static void main(String[] args) {
char c = '耰';
int x = 200;
System.out.println(c + x);
}
Đầu ra của bảng điều khiển: 33016 Chúng tôi đã phát hiện ra rằng耰tương ứng với mã 32816. Và khi chúng tôi cộng số này với 200, chúng tôi nhận được chính xác kết quả của mình - 33016 :) Cơ chế hoạt động, như bạn có thể thấy, khá đơn giản.
GO TO FULL VERSION