2016-07-27 11 views
5

Tôi đang cố gắng viết lại ứng dụng Android của mình trên Kotlin và tôi gặp sự cố khi chuyển đổi lớp hợp đồng ContentProvider. Vì vậy, tôi có lớp học đơn giản hợp đồng (thứ mặc định như kiểu nội dung và URI nội dung được bỏ qua):Kotlin cho lớp học cuối cùng bên trong android và tĩnh

public final class Contract { 
    public static final class Contacts { 
     public static final String NAME = "Name" 
     public static final String BIRTH = "Birth" 
     public static final String IMAGE = "Image" 
    } 
} 

Nếu tôi hiểu đúng, trong Kotlin chúng ta không có các thành viên tĩnh. Thay vì điều này, chúng tôi có "đối tượng đồng hành". Vì vậy, sau khi chuyển đổi nó cho Kotlin, tôi có mã này:

object BirthdayContract { 
    class Contacts : BaseColumns { 
     companion object { 
      val NAME = "Name" 
      val BIRTH = "Birth" 
      val IMAGE = "Image" 
     } 
    } 
} 

Nhưng khi tôi đang cố truy cập các trường như Contract.Contacts.NAME, tôi có lỗi: "NAME có quyền truy cập riêng tư". Thay đổi các công cụ sửa đổi hiển thị không có hiệu lực. Vì vậy, có một số cách để sử dụng các lớp hợp đồng như vậy trong Kotlin, hoặc tốt hơn để giữ nó trong Java?

UPD Tôi nghĩ rằng tôi nên làm rõ - mã người gọi của tôi cũng có trong Kotlin. Sự cố xảy ra ở chú thích @JvmField. Với nó, tôi có thể truy cập các thành viên tĩnh trực tiếp, mà không cần gọi getters.

+0

Vui lòng cung cấp [MCVE] (http://stackoverflow.com/help/mcve). Tôi đã dán 'BirthdayContract' của bạn vào một tệp Kotlin mới, loại bỏ': BaseColumns' vì nó không biên dịch với nó, và tạo ra một hàm truy cập 'BirthdayContract.Contacts.NAME'. Tôi tin rằng bạn cần cung cấp thêm thông tin và/hoặc các ví dụ được cập nhật để biên soạn và chứng minh vấn đề bạn đang thấy. Cảm ơn. – mfulton26

+0

@ mfulton26 Tôi đã làm điều tương tự - tạo tệp .kt mới và sao chép mã Kotlin của tôi bên trong. Nó biên dịch mà không có lỗi. Không có vấn đề gì với giao diện BaseColumns. Bạn có lỗi gì? – noktigula

Trả lời

3

NAME là thuộc tính và theo mặc định trường sao lưu của nó có quyền truy cập riêng tư. Nhưng vì nó là một tài sản, có một getter cho nó: getNAME().

Vì đây không phải là cách tự nhiên bạn truy cập hằng trong Java, có một vài cách để trực tiếp tiếp xúc với lĩnh vực này:

  1. const: const val NAME = "Name"
  2. @JvmField chú thích: @JvmField val NAME = "Name"
+0

@JvmField hoạt động tốt cho tôi, cảm ơn! Tuy nhiên, "const" và "@JvmStatic" không ảnh hưởng gì cả. – noktigula

0

xem xét sử dụng plain đối tượng như sau:

object Contract { 
    object Contacts { 
     val NAME = "Name" 
     val BIRTH = "Birth" 
     val IMAGE = "Image" 
    } 
} 

Điều này hoàn toàn nên điền vào mã Java ban đầu của bạn.

Trong phiên bản mới nhất Kotlin-Version công khai là chế độ hiển thị mặc định.

Optionially bạn có thể thêm const khóa từ cho các hằng số thời gian biên dịch để họ có thể sử dụng trong các chú thích .: https://kotlinlang.org/docs/reference/properties.html#compile-time-constants

@JvmStatic chú thích là dành cho Java Interop và nếu bạn có kế hoạch để đi đầy đủ kotlin bạn sẽ không cần nó.

0

Bạn có thể làm điều đó với một @JvmStatic

object BirthdayContract { 
    class Contacts : BaseColumns { 
     companion object { 
      @JvmStatic val NAME = "Name" 
      @JvmStatic val BIRTH = "Birth" 
      @JvmStatic val IMAGE = "Image" 
     } 
    } 
} 

//Java 
BirthdayContract.Contacts.Companion.getNAME() 

Cho đến nay tôi thấy không có lý do chính đáng để mở rộng BaseColumns, do đó, một lựa chọn tốt hơn whould được

object BirthdayContract { 
    object Contacts { 
      const val NAME = "Name" 
      const val BIRTH = "Birth" 
      const val IMAGE = "Image" 

    } 
} 
//Java 
BirthdayContract.Contacts.NAME 

Điểm mấu chốt là đối tượng lồng nhau trong kotlin trông không sạch sẽ. Vui lòng xem xét đơn giản hóa mã của bạn

2

Để vạch trần hằng như lĩnh vực, chú thích chúng bằng @JvmField

class Contacts { 
    companion object { 
     @JvmField val NAME = "Name" 
     @JvmField val BIRTH = "Birth" 
     @JvmField val IMAGE = "Image" 
    } 
} 

Sau đó, bạn có thể sử dụng chúng từ Java như thế này:

String name = Contacts.NAME; 

Một khi tất cả các mã của bạn là trong Kotlin, bạn có thể xóa chú thích @JvmField.

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