Scala tương đương với Java java.lang.Class <T> Object


183

Câu hỏi được giải thích tốt nhất bằng một ví dụ:

Trong Java cho JPA EntityManager, tôi có thể thực hiện các thao tác sau (Tài khoản là lớp Thực thể của tôi):

Account result = manager.find(Account.class, primaryKey);

Ở Scala, nỗ lực ngây thơ của tôi là:

val result = manager.find(Account.class, primaryKey)

Nhưng khi tôi cố gắng sử dụng Account.classtrong Scala, nó dường như không thích điều này. Làm cách nào tôi có thể chỉ định đối tượng java.lang.Class cho lớp Tài khoản trong Scala?


VonC đã cung cấp câu trả lời, nhưng hãy xem câu hỏi / câu trả lời của riêng tôi trên Scala & Erasure. Tôi nghĩ rằng nó có thể cung cấp cho bạn những ý tưởng để làm mọi thứ theo một cách khác với những gì bạn đang cố gắng.
Daniel C. Sobral

Câu trả lời:


263

Theo " Hệ thống kiểu Scala ",

val c = new C
val clazz = c.getClass              // method from java.lang.Object
val clazz2 = classOf[C]             // Scala method: classOf[C] ~ C.class
val methods = clazz.getMethods      // method from java.lang.Class<T>

Các classOf[T]phương thức trả về các đại diện thời gian chạy cho một loại Scala. Nó tương tự như biểu thức Java T.class.
Sử dụng classOf[T]là thuận tiện khi bạn có một loại mà bạn muốn thông tin, trong khi getClassthuận tiện để lấy thông tin tương tự từ một thể hiện của loại.

Tuy nhiên, classOf[T]getClasstrả về các giá trị hơi khác nhau, phản ánh hiệu ứng xóa kiểu trên JVM, trong trường hợp getClass.

scala> classOf[C]
res0: java.lang.Class[C] = class C

scala> c.getClass
res1: java.lang.Class[_] = class C

Đó là lý do tại sao những điều sau đây sẽ không hoạt động :

val xClass: Class[X] = new X().getClass //it returns Class[_], nor Class[X]

val integerClass: Class[Integer] = new Integer(5).getClass //similar error

Có một vé liên quan đến loại trả lạigetClass .

( James Moore báo cáo rằng vé là "ngay bây giờ", tức là tháng 11 năm 2011, hai năm sau, đã được sửa.
Trong 2.9.1, getClasshiện tại:

scala> "foo".getClass 
       res0: java.lang.Class[_ <: java.lang.String] = class java.lang.String

)

Trở lại năm 2009:

Sẽ rất hữu ích nếu Scala coi việc trả về từ getClass () là java.lang.Class [T] forSome {val T: C} trong đó C là một dạng giống như xóa biểu thức tĩnh của biểu thức mà getClass là gọi là

Nó sẽ cho phép tôi làm một cái gì đó như sau đây khi tôi muốn hướng nội vào một lớp nhưng không cần một thể hiện của lớp.
Tôi cũng muốn giới hạn các loại lớp tôi muốn hướng nội, vì vậy tôi sử dụng Lớp [_ <: Foo]. Nhưng điều này ngăn tôi vượt qua trong một lớp Foo bằng cách sử dụng Foo.getClass () mà không cần diễn viên.

Lưu ý: liên quan getClass, một cách giải quyết có thể sẽ là:

class NiceObject[T <: AnyRef](x : T) {
  def niceClass : Class[_ <: T] = x.getClass.asInstanceOf[Class[T]]
}

implicit def toNiceObject[T <: AnyRef](x : T) = new NiceObject(x)

scala> "Hello world".niceClass                                       
res11: java.lang.Class[_ <: java.lang.String] = class java.lang.String

4
FYI, Vé @VonC được đề cập đã được đánh dấu cố định vào ngày 22 tháng 6/11. Trong 2.9.1, getClass hiện có: scala> "foo" .getClass res0: java.lang.Class [_ <: java.lang.String] = class java.lang.String
James Moore

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.