2015-02-18 13 views
53

Tại sao bản in này 1?Tại sao trộn + và truyền không tạo ra lỗi trong "+ (int) + (dài) -1"?

import java.util.*; 
import java.lang.*; 
import java.io.*; 


class Main 
{ 
    public static void main (String[] args) throws java.lang.Exception 
    { 
     // your code goes here 
     System.out.println((byte)+(short)-(int)+(long)-1); 
    } 
} 

Chúng ta có thể kết hợp đúc và +,- toán tử đơn nhất? Tôi biết rằng chúng ta có thể làm nhiều lần, nhưng tại sao không đặt + ,- các toán tử đơn nhất ở giữa việc tạo ra một lỗi?

+23

Những '+' và '-' này là những con số đơn nhất. – johnchen902

+6

Đọc các thao tác từ phải sang trái. – DmitryKanunnikoff

+0

Tôi nghĩ rằng các câu hỏi "[giải thích mã này làm gì] (http://meta.stackoverflow.com/q/253894/1090562)" là off-topic ở đây. Điều gì khiến cho điều này trở thành ngoại lệ? –

Trả lời

80

Bạn không thêm hoặc trừ đi. Các toán tử + và - đó là các toán tử ký hiệu đơn nhất.

Xem documentation tại Bộ phận vận hành đơn nhất.

Chuỗi bị đe dọa:

(byte)+(short)-(int)+(long)-1 

được đánh giá từ phải sang trái như thế này:

giá trị ban đầu là -1
đúc để lâu (mà vẫn còn -1)
dấu + đơn (vẫn -1)
truyền tới int (vẫn -1)
unary - sign (bây giờ giá trị là 1)
vv (giá trị vẫn là 1 cho đến cuối cùng)

39

Những +- là những unary.

Cụ thể hơn, nó là trong thực tế:

System.out.println((byte) (+((short) (-((int) (+((long) -1))))))); 
+13

Woah ở đó, từ khi nào Java trở thành Lisp? :) – Doorknob

+0

@Doorknob - Đó là không có nơi gần đủ dấu ngoặc đơn để được so sánh với Lisp: P –

+0

Người hỏi dường như đã ý thức được rằng đó là những nhà khai thác unary, mà làm cho câu trả lời này không có vẻ đặc biệt hữu ích, nhưng có lẽ đó chỉ là tôi. – Dukeling

12

nếu bạn loại bỏ tất cả đúc từ ví dụ của bạn, bởi vì trong trường hợp này nó sẽ không làm gì cả

System.out.println((byte)+(short)-(int)+(long)-1);

sẽ trở thành

System.out.println( + - + -1);

bây giờ bạn có thể thấy rằng chỉ các nhà khai thác vẫn còn ở đó và vì trừ và trừ là cộng kết quả của bạn sẽ là 1

về cơ bản bạn có thể nghĩ về nó thích:

var mylong = +(long)-1;  <- -1 
var myint = -(int)mylong; <- 1 
var myshort = +(short)myint; <- 1 
var mybyte = (byte)myshort; <- 1 
+1

Ví dụ cộng/trừ là gây hiểu lầm. Không có phép cộng/trừ nào có liên quan trong ví dụ. –

+0

@SalmanA, nó gây nhầm lẫn gấp đôi, bởi vì không có thêm/chất nền diễn ra trong ví dụ. –

+0

Đó cũng là cú pháp không hợp lệ - tôi đã thực hiện chỉnh sửa để sửa ví dụ. – Random832

7

Tôi biết chúng tôi có thể thực hiện truyền nhiều lần. Nhưng đặt +, - toán tử đơn nhất ở giữa không đưa ra lỗi?

Nó chỉ đơn giản là hậu quả của sự nhất quán ngữ pháp của Java.Khi bạn viết

+ 1 

gì bạn thực sự đã viết là một unary số biểu hiện đó phân hủy thành hai phần:

  1. toán tử cộng chỉ hành: +
  2. một số biểu hiện , trong này trường hợp int chữ số 1.

Một ví dụ về một số biểu hiện là một biểu cast (còn unary):

(int) 1 

Vì vậy, bạn có thể thay thế này cho bản gốc 1 trên:

+ (int) 1 

tái phạm hành vi cùng một quá trình nhất quán, chúng ta có thể kết thúc với một biểu hiện lồng nhau đơn nhất về độ phức tạp tùy ý. Để quay lại câu hỏi chính của bạn:

tại sao?

Vì Java thực sự cần quy tắc cụ thể đối với các biểu thức như vậy.

Các vấn đề liên quan