Tôi có một số mã Java di sản mà định nghĩa một generic payload
biến đâu đó ngoài tầm kiểm soát của tôi (tức là tôi không thể thay đổi loại của nó):Trộn Scala và Java: Làm thế nào để có được tham số hàm tạo kiểu gõ chung phải không?
// Java code
Wrapper<? extends SomeBaseType> payload = ...
tôi nhận một giá trị như payload
như một tham số phương pháp trong mã của tôi và muốn chuyển nó vào một Scala case class
(để sử dụng như thông báo với một hệ thống diễn viên), nhưng không nhận được các định nghĩa đúng như vậy mà tôi không nhận được ít nhất một cảnh báo trình biên dịch.
// still Java code
ScalaMessage msg = new ScalaMessage(payload);
này đưa ra một cảnh báo trình biên dịch "Loại an toàn: contructor ... thuộc loại thô ..."
Các Scala case class
được định nghĩa là:
// Scala code
case class ScalaMessage[T <: SomeBaseType](payload: Wrapper[T])
Làm thế nào tôi có thể xác định các trường hợp lớp như vậy mà mã biên dịch sạch? (Buồn thay, thay đổi mã của lớp Java Wrapper
hoặc kiểu của tham số payload
không phải là một lựa chọn)
Cập nhật để làm rõ nguồn gốc của tải trọng tham số
Added Để so sánh, trong Java Tôi có thể xác định tham số giống như cách biến số payload
được xác định:
// Java code
void doSomethingWith(Wrapper<? extends SomeBaseType> payload) {}
và gọi nó là acco rdingly
// Java code
doSomethingWith(payload)
Nhưng tôi không thể khởi tạo, ví dụ: một đối tượng Wrapper trực tiếp mà không nhận được cảnh báo "kiểu thô". Ở đây, tôi cần phải sử dụng một phương pháp static
helper:
static <T> Wrapper<T> of(T value) {
return new Wrapper<T>(value);
}
và sử dụng helper tĩnh này để tạo một đối tượng Wrapper
:
// Java code
MyDerivedType value = ... // constructed elsewhere, actual type is not known!
Wrapper<? extends SomeBaseType> payload = Wrapper.of(value);
Giải pháp
tôi có thể thêm một phương pháp helper tương tự đối tượng đồng hành Scala:
// Scala code
object ScalaMessageHelper {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
new ScalaMessage(payload)
}
object ScalaMessageHelper2 {
def apply[T <: SomeBaseType](payload: Wrapper[T]) =
ScalaMessage(payload) // uses implicit apply() method of case class
}
và sử dụng từ Java để nhanh chóng lớp ScalaMessage
w/o vấn đề:
// Java code
ScalaMessage msg = ScalaMessageHelper.apply(payload);
Trừ khi ai đó đến với một giải pháp thanh lịch hơn, tôi sẽ trích xuất này như một câu trả lời ...
Cảm ơn bạn !
Sẽ không làm việc như tôi thực sự có một tham số phương pháp của loại 'Wrapper mở rộng SomeBaseType> 'trong Java được truyền vào khối mã mà chúng ta đang thảo luận. Tôi sẽ cập nhật câu hỏi gốc cho phù hợp. –
Tôi đã cập nhật, hãy kiểm tra. –