我创建了一个java代理类,它只使用java.lang.Instrumentation.getAllLoadedClasses()来检索一个类的数组,我通过它迭代,并打印它们的全名。
我使用此命令来运行此代理:
java -javaagent:<agent_jar> -jar <sample_jar>
<agent_jar>
包含我的代理类,而<sample_jar>
只包含一个空主方法的类(因为我必须将一些类/ jar传递给{{1}命令)
所以,基本上,它打印了JVM加载的所有默认类,这里是包含&#39; String&#39;的类名称的片段。和&#39;对象&#39;在他们的名字中:
(输出格式:Class.getName() - Class.getTypeName())
java
为什么有许多类的数组条目,例如。对象和对象[]?
答案 0 :(得分:0)
必须加载它,因为Java中的每个类都是扩展Object
类,或者我们可以说Object是Java中每个类的超类。
因此,当您打印出已加载的类时,它将显示Object
类。
来自Oracle Docs:
java.lang包中的Object类位于顶部 类层次结构树。每个班级都是直系或间接的后代, Object类的。您使用或编写的每个类都继承 Object的实例方法。
来自here:
类加载器
在JVM中,每个类都由一个实例加载 java.lang.ClassLoader中。 ClassLoader类位于 java.lang包和开发人员可以自由地将它子类化以添加它们 自己的类加载功能。
每当通过键入java MyMainClass启动新的JVM时,“bootstrap类加载器”负责加载关键的Java类 像java.lang.Object和其他运行时代码首先进入内存。 运行时类打包在JRE \ lib \ rt.jar文件中。我们 无法在Java中找到bootstrap类加载器的详细信息 文档,因为这是一个本机实现。对于相同的 原因,bootstrap类加载器的行为也会有所不同 跨越JVM。
答案 1 :(得分:0)
为什么有许多类的数组条目,例如。对象和对象[]?
只是您应用的类和/或JVM的默认应用程序启动器代码参考。
将加载Object
类,因为其他类继承了它。当启动器使用反射来查找Object[]
方法的Method
对象时,最有可能使用main(String[])
数组类型。
有一堆黑魔法&#34;当JVM引导自身时,会发生在幕后。如果真的需要知道,那么源代码就可用了....
(您的代理的类和依赖项也可能会显示在列表中,但它们也可能由不同的类加载器加载。)
答案 2 :(得分:0)
如果您致电main(String[] args)
,则需要Object
(因为所有内容都延伸Object
),String[]
和String
。
现在看一下String
的导入,您会认识到一些:
import java.io.ObjectStreamField;
import java.io.UnsupportedEncodingException;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.Formatter;
import java.util.Locale;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;
不会因为导入类而立即加载类。但是当你调用main
方法时,JVM之前会进行一些处理,例如解析参数并将它们写入args
数组。不难想象你列出的某些课程是必需的。