2016-04-20 29 views
-2

在我們的Java項目中的一個,我發現下面的代碼啓動一個線程:開始在Java線程和運算符優先級

new WorkerThread(socket).start(); 

現在根據operator precedence在Java中這是錯誤!它應該是代替:

(new WorkerThread(socket)).start(); 

現在我的問題:

爲什麼還工作嗎?有什麼危險嗎?

僅供參考,的WorkerThread實現非常簡單:

private class WorkerThread extends Thread 
{ 
    private Socket socket; 

    public WorkerThread(Socket socket) 
    { 
     super(); 
     this.socket = socket; 
    } 

    @Override 
    public void run() 
    { 
     try 
     { 
      /* do stuff... */ 
     } 
     catch (IOException e) 
     { 
     } 
     finally 
     { 
      socket.close(); 
     } 
    } 
} 
+2

爲什麼要根據運營商的優先級調用錯誤?你創建一個新的對象,然後你調用start方法... – GHajba

+0

你從哪裏聽說這是錯誤的? – SomeJavaGuy

+0

根據Java語法,它沒有什麼不對,它是完全有效的。 – cyroxis

回答

1

那麼,你鏈接到的網站是錯誤的,或至少不完整。首先,Java語言規範沒有明確定義運算符優先級。運算符優先級由語法隱式定義。 「.」運算符(儘管JLS不稱它爲運算符)也沒有單個優先級。

例如,下面的代碼是合法的,並做你所期望的:

class A { 
    static class B { 
     void f() { 
      System.out.println("f()"); 
     } 
    } 
} 

public class Foo {  
    public static void main(String... args) { 
     new A.B().f(); 
    } 
} 

new -expression如下paranthesized:(new A.B()).f();。所以顯然這個點的優先級高於和低於new。訣竅是點出現在不同的規則中。在該示例中,第一個點由規則ClassOrInterfaceTypeToInstantiateJLS section 15.9中生成,而第二個點由規則MethodInvocationJLS section 15.12中生成。

1

有沒有什麼 「危險」。

對鏈中前一個對象調用start方法,該方法似乎在延長Thread

這不是關於運算符優先級,而是正確的括號,在這種情況下,它是完全正確的。

您可能會發現括號相關的其他情況,例如,在內聯中投射並調用一個方法給鑄造對象時。

這裏的括號以便相關的種臺,例如鑄造時:

class A { 
    void a(){} 
} 
class B extends A { 
    void b(){} 
} 

A a = new B(); 
(B)a.b(); // won't compile 
((B)a).b(); // fine 
+0

那麼,* WorkerThread(套接字)*是一個類,而不是一個對象。 – chrset

+1

@chrset no。它是'WorkerThread'的一個實例,因爲你調用'new WorkerThread(socket)',這是對其構造函數的調用,從而返回一個實例。 – Mena

+0

不,因爲。作爲「新」具有更高的優先級。因此,它首先評估* WorkerThread(套接字)。開始()*,然後*新* – chrset

1

運算符優先級是不是在這裏思考,作爲唯一的運營商是new操作。

因此,它創建一個新對象,然後調用方法start()