Đặc tả số L (dài) của Java


95

Có vẻ như khi bạn nhập một số trong Java, trình biên dịch sẽ tự động đọc nó dưới dạng số nguyên, đó là lý do tại sao khi bạn nhập (dài) 6000000000(không phải trong phạm vi của số nguyên), nó sẽ phàn nàn rằng đó 6000000000không phải là số nguyên. Để sửa điều này, tôi đã phải chỉ định 6000000000L. Tôi vừa mới biết về đặc điểm kỹ thuật này.

Có các thông số kỹ thuật số khác như short, byte, float, double không? Có vẻ như những điều này sẽ tốt nếu có vì (tôi giả sử) nếu bạn có thể chỉ định số bạn đang nhập là số ngắn thì java sẽ không phải truyền nó - đó là một giả định, hãy sửa cho tôi nếu tôi sai . Tôi thường tự tìm kiếm câu hỏi này, nhưng tôi không biết loại thông số kỹ thuật số này thậm chí còn được gọi là gì.

Câu trả lời:


174

Có các hậu tố cụ thể cho long(ví dụ 39832L), float(ví dụ 2.4f) và double(ví dụ -7.832d).

Nếu không có hậu tố, và nó là một kiểu tích phân (ví dụ 5623), nó được giả định là một int. Nếu nó không phải là một loại tích phân (ví dụ 3.14159), nó được giả định là a double.

Trong mọi trường hợp khác ( byte, short, char), bạn cần các diễn viên như không có cụ thể hậu tố.

Đặc tả Java cho phép cả hậu tố chữ hoa và chữ thường, nhưng phiên bản chữ hoa cho longs được ưu tiên hơn, vì chữ hoa Lít dễ nhầm lẫn với chữ số 1hơn chữ thường l.

Xem phần 3.10 của JLS để biết chi tiết về máu (xem định nghĩa của IntegerTypeSuffix).


9
Nhập cảnh muộn: loại bỏ các nguồn tiềm ẩn của sự mơ hồ luôn tốt và tôi không đồng ý ... nhưng tôi tin rằng nếu bạn thấy mình khó hiểu 1với l0với O(v.v.), ưu tiên của bạn là đặt đúng phông chữ (nếu bạn có thể ), sau đó lo lắng về việc đảm bảo bạn không bỏ lỡ phím Shift.
davidcsb

@SimonNickerson Tôi có câu hỏi về các hậu tố ... Nếu tôi khai báo biến dài hoặc biến kép như: long _lo = 30;và không 30L, điều này có nghĩa là biến của tôi sẽ được chuyển thành float ? Hoặc trong trường hợp _lo = _lo + 2.77đó _losẽ được đúc thành phao mặc dù nó đã được khai báo là dài
luigi7up

Không, phao không liên quan ở đây. Trong trường hợp đầu tiên, 30là một intđược tự động chuyển đổi thông qua chuyển đổi mở rộng thành a long. Trong trường hợp thứ hai, tuyên bố của bạn là bất hợp pháp. Bạn sẽ phải đúc một cách rõ ràng phía bên tay phải để dài, ví dụ_lo = (long) (_lo + 2.77)
Simon Nickerson

4
@DavidCesarino thay đổi phông chữ sẽ khắc phục sự mơ hồ cho bạn - trong trình chỉnh sửa cụ thể đó, nơi bạn đã đặt nó đúng. Việc thay đổi l thành L sẽ khắc phục sự mơ hồ cho tất cả những người có thể đã từng đọc mã của bạn, bao gồm cả chính bạn khi bạn đang đọc mã trong một Trình soạn thảo, IDE khác, xem mã nguồn trên web (công cụ đánh giá, kho lưu trữ, v.v.). IMHO ưu tiên là không bỏ lỡ phím Shift. Btw. phông chữ nào bạn đề xuất? Tôi thích monospace và nó là mặc định gần như trong tất cả các trình soạn thảo, CLI, v.v. mà tôi thấy và trong phông chữ này l1( 0Otương ứng) khá giống nhau.
dingalapadum

1
@dingalapadum Như tôi đã nói, bạn nói đúng. Loại bỏ các nguồn không rõ ràng chắc chắn là một việc làm đúng đắn. Tôi chỉ nói rằng bạn nên cố gắng không sử dụng bất kỳ trình soạn thảo nào mà bạn có thể dễ dàng nhầm lẫn chúng. Nói cách khác, gợi ý cũ về việc viết mã phòng thủ, nhưng không phụ thuộc vào nó. Về phông chữ, nó rất cá nhân, nhưng tôi luôn sử dụng Deja Vu Sans Mono bất cứ khi nào tôi có thể vì 1) nó là monospaced; 2) nó không có sự mơ hồ giữa các ký tự; và 3) Tôi thích hình dạng của nó, đẹp và duyên dáng, gần giống như một phông chữ sans-serif tốt, dễ đọc (các phông chữ lập trình tốt khác cảm thấy IMHO quá "kim loại").
davidcsb

13

Tôi hy vọng bạn sẽ không bận tâm một chút tiếp tuyến nào, nhưng nghĩ rằng bạn có thể quan tâm khi biết rằng ngoài F(đối với float), D(đối với kép) và L(đối với lâu dài), một đề xuất đã được đưa ra để thêm các hậu tố cho byteshort- YStương ứng . Điều này sẽ loại bỏ sự cần thiết phải truyền sang byte khi sử dụng cú pháp chữ cho mảng byte (hoặc ngắn). Trích dẫn ví dụ từ đề xuất:

LỢI ÍCH CHÍNH: Tại sao nền tảng tốt hơn nếu đề xuất được thông qua?

mã thô như

 byte[] stuff = { 0x00, 0x7F, (byte)0x80,  (byte)0xFF};

có thể được mã hóa thành

 byte[] ufum7 = { 0x00y, 0x7Fy, 0x80y, 0xFFy };

Joe Darcy đang giám sát Project Coin cho Java 7 và blog của anh ấy là một cách dễ dàng để theo dõi các đề xuất này.


Điều đó thật tuyệt ... Tôi luôn thấy rằng tất cả các diễn viên đều thực sự khó chịu
jbu 20-04-09

Tôi hiểu điều này đã không được đưa vào Java 7. Bạn có bất kỳ thông tin nào về việc nó sẽ trở thành một bản cập nhật trong tương lai hay Java 8 không?
nghiền nát

@crush Tôi đã thử xem xét nó một vài tháng trước, và theo như tôi có thể nói, đề xuất đã bị bỏ rơi. 0bMặc dù vậy, chúng tôi đã nhận được _ trong các ký tự số và tiền tố cho các ký tự nhị phân. Ầm ầm.
erickson

Đề xuất này có lẽ thực hiện trên Kotlin thay vì java, như oracle không muốn cộng đồng nói với họ làm thế nào để làm việc ... chúng tôi đang ở trên năm 2018 và vẫn không có gì về đề xuất này, thật đáng buồn
JoelBonetR

11

Theo mặc định, bất kỳ kiểu dữ liệu nguyên thủy tích phân nào (byte, short, int, long) sẽ được trình biên dịch java coi là kiểu int . Đối với byteshort , miễn là giá trị được gán cho chúng nằm trong phạm vi của chúng, không có vấn đề gì và không cần hậu tố. Nếu giá trị được gán cho byteshort vượt quá phạm vi của chúng, thì cần phải truyền kiểu rõ ràng.

Ví dụ:

byte b = 130; // CE: range is exceeding.

để khắc phục kiểu đúc biểu diễn này.

byte b = (byte)130; //valid, but chances of losing data is there.

Trong trường hợp kiểu dữ liệu dài, nó có thể chấp nhận giá trị số nguyên mà không gặp bất kỳ rắc rối nào. Giả sử chúng ta chỉ định như

Long l = 2147483647; //which is max value of int

trong trường hợp này không cần có hậu tố như L / l. Theo mặc định giá trị 2147483647 được trình biên dịch java coi là kiểu int. Việc ép kiểu bên trong được thực hiện bởi trình biên dịch và int được tự động thăng cấp thành kiểu Long.

Long l = 2147483648; //CE: value is treated as int but out of range 

Ở đây, chúng ta cần đặt hậu tố là L để coi ký tự 2147483648 là kiểu dài bằng trình biên dịch java.

cuối cùng thì

Long l = 2147483648L;// works fine.


1

Có vẻ như những điều này sẽ tốt nếu có vì (tôi giả sử) nếu bạn có thể chỉ định số bạn đang nhập là ngắn thì java sẽ không phải truyền nó

Vì việc phân tích cú pháp các ký tự xảy ra tại thời điểm biên dịch, điều này hoàn toàn không liên quan đến hiệu suất. Lý do duy nhất để có shortbytehậu tố sẽ tốt là nó dẫn đến mã nhỏ gọn hơn.


0

Để hiểu tại sao cần phải phân biệt giữa nghĩa đen intvà nghĩa longđen, hãy xem xét:

long l = -1 >>> 1;

đấu với

int a = -1;
long l = a >>> 1;

Bây giờ như bạn mong đợi đúng, cả hai đoạn mã đều cung cấp cùng một giá trị cho biến l. Mà không thể phân biệt được intvà nghĩa longđen thì giải thích là -1 >>> 1gì?

-1L >>> 1 // ?

hoặc là

(int)-1 >>> 1 // ?

Vì vậy, ngay cả khi số nằm trong phạm vi phổ biến, chúng ta cần chỉ định loại. Nếu mặc định thay đổi theo độ lớn của chữ, thì sẽ có một sự thay đổi kỳ lạ trong cách giải thích các biểu thức chỉ từ việc thay đổi các chữ số.

Điều này không xảy ra đối với byte, shortcharvì họ luôn khuyến khích trước khi thực hiện phép toán số học và phép toán. Có thể cho rằng chúng phải là hậu tố kiểu số nguyên để sử dụng trong các biểu thức khởi tạo mảng, nhưng không phải vậy. floatsử dụng hậu tố fdouble d. Các chữ khác có các loại rõ ràng, có một loại đặc biệt cho null.


Tôi thực sự sẽ quan tâm đến những gì bạn có ý nghĩa trong những ngày trở lại. Trong cả hai trường hợp, tôi nhận được 2147483647 và tôi không hiểu tại sao tôi nên mong đợi điều gì đó khác.
Ngày

@TheincredibleJan Bạn đúng mong chờ Integer.MAX_VALUE, tuy nhiên nếu không có cách nào để phân biệt giữa intlongliterals nó sẽ là mơ hồ. / Tôi không nhớ gì về câu hỏi này, nhưng dù sao cũng đã làm rõ câu trả lời của mình.
Tom Hawtin - tackline
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.