Runnable 实例化 Java
Runnables Instantiation Java
我正在尝试像 Executors.newFixedThreadPool
中那样编写一个 ExecutorService
,并将 运行nable 作为参数提供给填充 ThreadPool
的方法。
这不是关于实例化一个内部 class 就像这里提议的 How to instantiate inner class with reflection in Java? 我实际上想要一个使用反射的替代方法。
线程池要运行的Runnable
是一个抽象运行ner的实例。由于以下原因导致的错误,我无法使用 testRunnable.newInstance()
或 testRunnable::new
创建实例:
java.lang.NoSuchMethodException: ...$MyRunner.() exception.
现在我通过反射来做这个:
public void doStuff() throws Exception {
MyRunner r = new MyRunner();
for (int i = 0; i < 10; i++) {
doMoreStuff(r.getClass(), this);
}
}
public void doMoreStuff(Class<? extends TestRunner> clazz, Object... params) throws Exception {
Class<?>[] types = Stream.of(params).map(Object::getClass).toArray(n -> new Class[n]);
TestRunner t = clazz.getConstructor(types).newInstance(params);
new Thread(t).start();
}
有更好的方法吗?
不清楚,你到底想做什么。如果你想做与你的问题相同但没有反思的事情,你可以简单地做
public void doStuff() {
for (int i = 0; i < 10; i++) {
doMoreStuff(new MyRunner());
}
}
public void doMoreStuff(TestRunner t) {
new Thread(t).start();
}
因为这就是您在问题代码中实际做的事情,它也与您在 中编写的内容相匹配:“我想通过将 runnable 的不同特化传递给 doMoreStuff()
方法”。您可以将 TestRunner
的任意特化传递给方法 doMoreStuff
…
您似乎想在方法 doMoreStuff()
中执行新实例的创建,而不是在调用方处执行,尽管您的问题没有提供任何关于 为什么 的提示。如果有正当理由,你可以这样做:
public void doStuff() {
for (int i = 0; i < 10; i++) {
doMoreStuff(MyRunner::new);
}
}
public void doMoreStuff(Supplier<? extends TestRunner> s) {
new Thread(s.get()).start();
}
虽然这样做会更自然:
public void doStuff() {
doMoreStuff(MyRunner::new);
}
public void doMoreStuff(Supplier<? extends TestRunner> s) {
for(int i = 0; i < 10; i++)
new Thread(s.get()).start();
}
这确实是将“十次”执行策略和执行哪个实现的决定分开了。
如果您的问题源于尝试允许将外部实例作为参数提供,则这不适用于 ::new
方法引用,因为这些方法始终将外部实例视为隐含和预绑定.在这种情况下,您必须求助于 lambda 表达式:
public void doStuff() {
doMoreStuff(outer -> outer.new MyRunner(), this);
}
public <T> void doMoreStuff(Function<T,? extends TestRunner> s, T context) {
for(int i = 0; i < 10; i++)
new Thread(s.apply(context)).start();
}
我正在尝试像 Executors.newFixedThreadPool
中那样编写一个 ExecutorService
,并将 运行nable 作为参数提供给填充 ThreadPool
的方法。
这不是关于实例化一个内部 class 就像这里提议的 How to instantiate inner class with reflection in Java? 我实际上想要一个使用反射的替代方法。
线程池要运行的Runnable
是一个抽象运行ner的实例。由于以下原因导致的错误,我无法使用 testRunnable.newInstance()
或 testRunnable::new
创建实例:
java.lang.NoSuchMethodException: ...$MyRunner.() exception.
现在我通过反射来做这个:
public void doStuff() throws Exception {
MyRunner r = new MyRunner();
for (int i = 0; i < 10; i++) {
doMoreStuff(r.getClass(), this);
}
}
public void doMoreStuff(Class<? extends TestRunner> clazz, Object... params) throws Exception {
Class<?>[] types = Stream.of(params).map(Object::getClass).toArray(n -> new Class[n]);
TestRunner t = clazz.getConstructor(types).newInstance(params);
new Thread(t).start();
}
有更好的方法吗?
不清楚,你到底想做什么。如果你想做与你的问题相同但没有反思的事情,你可以简单地做
public void doStuff() {
for (int i = 0; i < 10; i++) {
doMoreStuff(new MyRunner());
}
}
public void doMoreStuff(TestRunner t) {
new Thread(t).start();
}
因为这就是您在问题代码中实际做的事情,它也与您在 doMoreStuff()
方法”。您可以将 TestRunner
的任意特化传递给方法 doMoreStuff
…
您似乎想在方法 doMoreStuff()
中执行新实例的创建,而不是在调用方处执行,尽管您的问题没有提供任何关于 为什么 的提示。如果有正当理由,你可以这样做:
public void doStuff() {
for (int i = 0; i < 10; i++) {
doMoreStuff(MyRunner::new);
}
}
public void doMoreStuff(Supplier<? extends TestRunner> s) {
new Thread(s.get()).start();
}
虽然这样做会更自然:
public void doStuff() {
doMoreStuff(MyRunner::new);
}
public void doMoreStuff(Supplier<? extends TestRunner> s) {
for(int i = 0; i < 10; i++)
new Thread(s.get()).start();
}
这确实是将“十次”执行策略和执行哪个实现的决定分开了。
如果您的问题源于尝试允许将外部实例作为参数提供,则这不适用于 ::new
方法引用,因为这些方法始终将外部实例视为隐含和预绑定.在这种情况下,您必须求助于 lambda 表达式:
public void doStuff() {
doMoreStuff(outer -> outer.new MyRunner(), this);
}
public <T> void doMoreStuff(Function<T,? extends TestRunner> s, T context) {
for(int i = 0; i < 10; i++)
new Thread(s.apply(context)).start();
}