2011-10-19 34 views
11

Trong Scala, chúng ta có thể viếtTương đương Java của đối tượng Scala là gì?

object Foo { def bar = {} } 

Làm thế nào là thực hiện bởi trình biên dịch? Tôi có thể gọi Foo.bar(); từ Java nhưng new Foo(); từ Java cung cấp cho các lỗi cannot find symbol symbol: constructor Foo()

  • Liệu các singletons hỗ trợ JVM natively?
  • Có thể có một lớp trong Java không có hàm tạo không?

Lưu ý: đây là sản phẩm mã của scalac -print

package <empty> { 
    final class Foo extends java.lang.Object with ScalaObject { 
    def bar(): Unit =(); 
    def this(): object Foo = { 
     Foo.super.this(); 
    () 
    } 
    } 
} 

Trả lời

11

Hỗ trợ cho độc thân không phải là về mặt kĩ ngôn ngữ, nhưng ngôn ngữ cung cấp đủ cơ sở vật chất để tạo ra chúng mà không cần bất kỳ rắc rối.

Xét đoạn mã sau:

public class Singleton { 
    private static final Singleton instance = new Singleton(); 

    // Private constructor prevents instantiation from other classes 
    private Singleton() {} 

    public static Singleton getInstance() { 
     return instance; 
    } 
} 

Đây là một ví dụ từ Wikipedia, điều này giải thích làm thế nào một singleton có thể được thực hiện. Một cá thể được giữ trong một trường riêng, hàm tạo không thể truy cập được bên ngoài lớp, phương thức này trả về cá thể đơn lẻ này.

Đối với nhà xây dựng: mỗi lớp theo mặc định có một cái gọi là constructor mặc định mà không có đối số và chỉ cần gọi là không-args constructor của lớp cha. Nếu siêu lớp không có bất kỳ hàm tạo có thể truy cập nào không có đối số, bạn sẽ phải viết một hàm tạo rõ ràng.

Vì vậy, một lớp phải có một hàm tạo, nhưng bạn không phải viết nó nếu lớp cha có một hàm tạo không-arg.

+0

ah nên Bí quyết là để làm cho tin constructor. – Jus12

21

Khi biên dịch mã của bạn, Scala trình biên dịch tạo ra một tương đương với mã Java sau:

public final class Foo { 
    private Foo() {} // Actually, Foo doesn't have constructor at all 
        // It can be represented in bytecode, 
        // but it cannot be represented in Java language 

    public static final void bar() { 
     Foo$.MODULE$.bar(); 
    } 
} 

public final class Foo$ implements ScalaObject { 
    public static final Foo$ MODULE$; 
    static { 
     new Foo$(); 
    } 
    private Foo$() { MODULE$ = this; } 
    public final void bar() { 
     // actual implementation of bar() 
    } 
} 

Đây Foo$ là một thực hiện thực tế của một singleton, trong khi Foo cung cấp một phương pháp static để tương tác với Java.

+0

Có cách nào để xem mã Java "trung gian", như bạn đã trình bày không? Bạn đã sử dụng một trình biên dịch ngược để tạo ra nó? – Jus12

+1

@ Jus12: Có lẽ một số trình giải mã có thể hiển thị nó, nhưng tôi đã xây dựng lại nó theo cách thủ công từ đầu ra của 'javap -c -private Foo' /' javap -c -private Foo $ ' – axtavt

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