传递一个 class 名称作为字符串参数来创建实例
Pass a class name as string argument to create instance
是否有任何可能的方法将 class name/path 作为 String 参数传递以在运行时在代码中调用它?
我正在处理一些遗留代码,我无法在全球范围内更改它。为它创建新的集成建议我创建 class X 的新 copy,重命名它,并传递 [=15 的新实例=]Y 我是手动创建的。我的想法告诉我将 Y 作为某种参数传递并且永远不要再次复制 X。
我不太明白为什么你(认为)你需要做你想做的事(为什么首先复制class而不是不仅仅是使用它?为什么要传递 classname 而不是 class 本身?),但是,是的,您可以使用反射通过(完全限定的)名称实例化 classes。
首先你得到 class 本身的句柄:
val clazz = Class.forName("foo.bar.X")
然后,如果构造函数不需要任何参数,你可以这样做
val instance = clazz.newInstance
如果您需要将参数传递给构造函数,它会变得有点复杂。
val constructor = clazz.getConstructors().find { c =>
c.getParameters().map(_.getParameterizedType) == args.map(_.getClass)
}.getOrElse (throw new Exception("No suitable constructor found")
// or if you know for sure there will be only one constructor,
// could just do clazz.getConnstructors.headOption.getOrElse(...)
val instance = constructor.newInstance(args)
请注意,结果 instance
的类型为 Object
(AnyRef
),因此如果不强制转换为某种接口类型,您实际上无法使用它做很多事情您的 class 已知可以实施。
让我再说一遍:这很可能不是实现您实际尝试做的事情的最佳方式。如果您打开另一个问题并描述您的实际问题(而不是您尝试实施的解决方案),您可能会得到更有帮助的答案。
是否有任何可能的方法将 class name/path 作为 String 参数传递以在运行时在代码中调用它? 我正在处理一些遗留代码,我无法在全球范围内更改它。为它创建新的集成建议我创建 class X 的新 copy,重命名它,并传递 [=15 的新实例=]Y 我是手动创建的。我的想法告诉我将 Y 作为某种参数传递并且永远不要再次复制 X。
我不太明白为什么你(认为)你需要做你想做的事(为什么首先复制class而不是不仅仅是使用它?为什么要传递 classname 而不是 class 本身?),但是,是的,您可以使用反射通过(完全限定的)名称实例化 classes。
首先你得到 class 本身的句柄:
val clazz = Class.forName("foo.bar.X")
然后,如果构造函数不需要任何参数,你可以这样做
val instance = clazz.newInstance
如果您需要将参数传递给构造函数,它会变得有点复杂。
val constructor = clazz.getConstructors().find { c =>
c.getParameters().map(_.getParameterizedType) == args.map(_.getClass)
}.getOrElse (throw new Exception("No suitable constructor found")
// or if you know for sure there will be only one constructor,
// could just do clazz.getConnstructors.headOption.getOrElse(...)
val instance = constructor.newInstance(args)
请注意,结果 instance
的类型为 Object
(AnyRef
),因此如果不强制转换为某种接口类型,您实际上无法使用它做很多事情您的 class 已知可以实施。
让我再说一遍:这很可能不是实现您实际尝试做的事情的最佳方式。如果您打开另一个问题并描述您的实际问题(而不是您尝试实施的解决方案),您可能会得到更有帮助的答案。