Tôi đang cố gắng gọi phương thức newInstance
của một hàm tạo của lớp Scala (lớp chữ thường hoặc lớp thông thường, cả hai đều bị ảnh hưởng).Số lượng đối số sai khi gọi hàm tạo Scala bằng cách sử dụng phản chiếu
Tuy nhiên, tôi đang chạy vào một IllegalArgumentException
với gợi ý sai số đối số.
xem xét như sau:
case class Vec2(x: Float, y: Float)
object TestApp {
def main(args: Array[String]) {
//after some research I found the last constructor always to be the default
val ctor = classOf[Vec2].getConstructors.last
println("ctor = " + ctor)
println("takes parameters: " + ctor.getParameterTypes.length)
val params = new Array[Float](2)
params.update(0, 1.0f)
params.update(1, -1.0f)
println("num parameters: " + params.length)
println("trying to create new instance...")
try {
val x = ctor.newInstance(params)
println("new instance: " + x)
}
catch {
case ex => ex.printStackTrace
}
}
Đầu ra là như sau:
ctor = public pd.test.Vec2(float,float)
takes parameters: 2
num parameters: 2
trying to create new instance...
java.lang.IllegalArgumentException: wrong number of arguments
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:39)
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:27)
at java.lang.reflect.Constructor.newInstance(Constructor.java:513)
at pd.test.TestApp$.main(TestApp.scala:60)
at pd.test.TestApp.main(TestApp.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:115)
tôi đã trải qua một cái gì đó như thế này trong Java một lần. Trong trường hợp đó, lớp mà tôi cố gắng khởi tạo là lớp bên trong của một lớp khác, vì vậy Java mong đợi một tham số bổ sung tiềm ẩn, là đối tượng Class
của lớp kèm theo (nếu lớp được khai báo là tĩnh) hoặc một thể hiện của lớp kèm theo.
Tuy nhiên, trong trường hợp này không có lớp kèm theo là Vec2
, trừ khi Scala thêm một nội bộ (mặc dù, java.lang.Class.getEnclosingClass()
trả về null
cho tôi).
Vì vậy, câu hỏi của tôi là làm thế nào để khởi tạo các lớp Scala bằng cách sử dụng sự phản chiếu? Có bất kỳ thông số bổ sung nào mà các nhà xây dựng Scala mong đợi không?
'newInstance' loại bỏ các đối số của loại phụ" java.lang.Object', vì vậy bạn sẽ phải thực hiện một số thứ như 'ctor.newInstance (params.map (_. AsInstanceOf [Object]): _ *)' cho ' Float' –
Cảm ơn, điều đó đã giúp bạn! Cũng nhờ Vasil. Tôi đã không chạy vào vấn đề đó với lớp chung tôi đang làm việc trên, mà tạo ra một Array [AnyRef]. Ví dụ tôi đăng là một phiên bản đơn giản. :) – pdinklag
@Vasil Như với Java, Scala sẽ tự động hóa bất cứ thứ gì có một kiểu nguyên thủy cơ bản, do đó một Scala 'Float' có thể là' float' hoặc 'java.lang.Float'. Bởi vì scala varargs sử dụng 'Seq' và Seq là một kiểu bị xóa, bạn có thể chắc chắn rằng những gì bạn đang chuyển sẽ được đóng hộp và sẽ phân lớp' Object' –