为什么java反射将对象方法显示为实例的方法,而不是静态的?
默认java控制台应用程序运行传递的类,该类包含应使用静态修饰符声明的主方法为什么java反射将对象方法显示为实例的方法,而不是静态的?,java,scala,main,Java,Scala,Main,默认java控制台应用程序运行传递的类,该类包含应使用静态修饰符声明的主方法 $ scala Welcome to Scala version 2.10.3-20130923-000000-e2fec6b28d (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60). Type in expressions to have them evaluated. Type :help for more information. scala> impo
$ scala
Welcome to Scala version 2.10.3-20130923-000000-e2fec6b28d (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import java.lang.reflect.Modifier
import java.lang.reflect.Modifier
scala> object Main {
| def main(args : Array[String]) = println("hello")
| }
defined module Main
scala> val method = Main.getClass.getMethod("main", classOf[Array[String]])
method: java.lang.reflect.Method = public void Main$.main(java.lang.String[])
scala> Modifier.isStatic( method.getModifiers )
res0: Boolean = false
所以,我尝试将此类类创建为object,而不是直接使用静态修饰符。但令人惊讶的是,我得到了没有静态修饰符的main方法
$ scala
Welcome to Scala version 2.10.3-20130923-000000-e2fec6b28d (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_60).
Type in expressions to have them evaluated.
Type :help for more information.
scala> import java.lang.reflect.Modifier
import java.lang.reflect.Modifier
scala> object Main {
| def main(args : Array[String]) = println("hello")
| }
defined module Main
scala> val method = Main.getClass.getMethod("main", classOf[Array[String]])
method: java.lang.reflect.Method = public void Main$.main(java.lang.String[])
scala> Modifier.isStatic( method.getModifiers )
res0: Boolean = false
所以Main对象包含实际上不是静态的Main方法
我想使用java命令来运行scala类,而不是特定的scala命令
如何从scala对象中获取静态main方法
更新:
建议搜索具有相同名称的类,但该类没有“$”符号作为后缀。所以,我继续REPL会话,试图找到这个类
scala> val loader = Main.getClass.getClassLoader
loader: ClassLoader = scala.tools.nsc.interpreter.IMain$TranslatingClassLoader@fdf3a48
scala> val mc = Class.forName("Main", true, loader)
java.lang.ClassNotFoundException: Main
at scala.tools.nsc.interpreter.AbstractFileClassLoader.findClass(AbstractFileClassLoader.scala:69)
at java.lang.ClassLoader.loadClass(ClassLoader.java:425)
at java.lang.ClassLoader.loadClass(ClassLoader.java:358)
at java.lang.Class.forName0(Native Method)
at java.lang.Class.forName(Class.java:270)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:7)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:734)
at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:983)
at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:573)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:604)
at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:568)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:756)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:801)
at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:774)
at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:801)
at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:713)
at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:577)
at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:584)
at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:587)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:878)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833)
at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:833)
at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:833)
at scala.tools.nsc.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
我可能认为我需要从scala编译器utils调用特殊函数,以获得定义类的包装器
解决了的:
我做了更多的实验,并确认scalac行为与scala REPL不同。第一个类为每个对象生成额外的类,该类将对象的方法作为静态的。如果您创建一个类和它的同伴对象,那么同伴的方法将被添加到关联的类中,而无需创建额外的代理。这适用于任何方法,即使是那些签名不同于主方法签名的方法,Scala编译器也会创建一个静态主方法:
$ cat Main.scala
object Main {
def main(args: Array[String]) = println("hello")
}
$ scalac Main.scala
$ ls *class
Main.class Main$.class
$ javap -cp . Main
Compiled from "Main.scala"
public final class Main {
public static void main(java.lang.String[]);
}
$ javap -cp . Main$
Compiled from "Main.scala"
public final class Main$ {
public static final Main$ MODULE$;
public static {};
public void main(java.lang.String[]);
}
$ java -cp /usr/local/scala/lib/scala-library.jar:. Main
hello
我将在real one出现后立即删除此答案,但这并不是因为scala没有静态方法,问题在于[错误?]使用java反射进行此类检查:
/tmp » echo 'object Main { def main(args : Array[String]) = println("hello") }' > Main.scala
/tmp » scalac Main.scala
/tmp » javap Main
Compiled from "Main.scala"
public final class Main {
public static void main(java.lang.String[]);
}
如果反编译此文件:
package test
import java.lang.reflect.Modifier
object Main {
def main(args: Array[String]): Unit = {
val method = Main.getClass.getMethod("main", classOf[Array[String]])
println(Modifier.isStatic(method.getModifiers)) // false
println(Main.getClass.getName()); // test.Main$
val act = Class.forName("test.Main");
val method2 = act.getMethod("main", classOf[Array[String]])
println(Modifier.isStatic(method2.getModifiers)) // true !!!
}
}
您将看到两个类:
一,
二,
谷歌搜索scala静态方法消除了所有的歧义:scala没有静态。Java静态方法的等价物是对象中的函数。@vptheron。。。op期望对象方法是静态的,但反射则相反。最后一个错误只与REPL的使用有关:其中定义的类正在被包装
public final class Main
{
public static void main(String[] paramArrayOfString)
{
...
}
}