我对这是如何工作有一些疑问,考虑一个简单的Java程序:
package com.example;
public class Test {
public static void main(String[] args) {
Test t = new Test(); (1) <---- How is this possible
t.print();
}
public void print() {
System.out.println("This is demo");
}
}
这是非常简单的计划。
但是,我怀疑(1)。我们正在创建一个Test实例,但这仍然在Class Test的定义中。这怎么可能?
任何有助于此的解释都会很棒。
答案 0 :(得分:2)
将在运行时创建实例。
到那时,编译时已结束,应用程序的所有代码(包括所有类定义)都将“准备就绪”。
即使您调用JVM尚未遇到的类的构造函数,它也会在执行构造函数调用之前动态加载类(完整地)。注意:a)这可能实际上在运行时失败,在这种情况下你得到一个ClassNotFoundError,和b)在你的情况下不会发生,因为你从它自己调用类的构造函数(所以它必须已经加载)。
在编译期间,编译器不会运行任何代码(甚至不包括静态初始化程序)。
但它确实(在编译期间)您尝试调用的每个方法或构造函数确实存在。同样,这在理论上可能在运行时失败(如果你搞乱了类文件),在这种情况下你会得到一个NoSuchMethodError。
答案 1 :(得分:1)
问:Test t = new Test(); (1) <---- How is this possible
答:因为&#34;静电&#34;在public static void main(String[] args)
&#34;静态&#34;意味着方法&#34; main()&#34;是任何特定类对象的独立。
您可以创建任何所需的类对象 - 包括新的&#34;测试&#34;对象
定义&#34; main&#34;的好处之一是静态的,你可以使用&#34; main()&#34;作为班级的测试方法。每个类都可以拥有它自己的&#34; main&#34;,您可以通过在Java命令行中指定该类来单独测试每个类。
例如:
public class MyClass {
public int add2(int n) {
return n + 2;
}
public static void main (String[] args) {
MyClass unitTest = new MyClass ();
System.out.println ("add2(2)=" + unitTest.add2(2));
System.out.println("Expected result=4");
}
}
然后测试如下:
javac MyClass.java
java MyClass
add2(2)=4
Expected result=4
这个问题实际上已被多次询问和回答。例如:
Why is the Java main method static?
=============================================== ===================
以下是一些说明这一点的例子:
public class CreateMyself {
private int value = 0;
private static CreateMyself m_singleton = null;
// EXAMPLE 1: You can legally create an instance in the constructor ...
public CreateMyself () {
value++;
// CreateMyself o = new CreateMyself (); // BAD!!! This will cause infinite recursion and crash your stack!!!
System.out.println ("Leaving constructor, value=" + value + "...");
}
// EXAMPLE 2: You can legally create another instance in a normal class member
public void createAnother() {
// But ... WHY??? Is there anything you can't do directly, in your own instance?
CreateMyself newInstance = new CreateMyself ();
System.out.println ("Leaving createAnother, value=" + value + "...");
}
// EXAMPLE 3: This is a common idiom for creating a "singleton"
// NOTE: for this to work, you'd also make the constructor PRIVATE (or protected), so the client *must* call "getInstance()", instead of "new".
public static CreateMyself getInstance () {
if (m_singleton == null) {
m_singleton = new CreateMyself ();
}
System.out.println ("returning singleton instance...");
return m_singleton;
}
// EXAMPLE 4: Creating an instance in "static main()" is a common idiom
public static void main (String[] args) {
CreateMyself newInstance = new CreateMyself ();
newInstance.createAnother ();
}
}
还有许多其他可能的用途。例如,您可能会有一个静态方法来执行数据库查找并返回匹配对象的列表。
请注意,大多数情况下,如果某个类对其创建自身实例的方法非常有用,则可能是 static 方法。
答案 2 :(得分:1)
首先我们必须使用javac
编译此Porgram编译后它将提供Class
文件。
现在是时候执行Class
使用调用java
的{{1}}并将JVM
文件加载到Class
了。
Class Loader
在这里
java fileName.Class
我们所知道的 public static void main(String[] args) {
Test t = new Test(); (1) <---- How is this possible
t.print();
}
内容(它是变量或Java中的方法)static
加载ClassLoader
时加载的类
如您所见Class
方法是Main
方法。因此,它会自动加载到static
ClassLoader
文件中。
现在class
首先在课堂上找到JVM
。这是静态内容意味着它是类的一部分,但不是类 public static void main(String... args)
的一部分。 Instance
实例无需调用此Class
方法。
Main
将在未获取main(String... args)
实例的情况下被调用。在Class
方法中,您的课程正在获取Main
Instantiated
现在因为类已加载到类Loader Test t = new Test(); \\here t is reference Variable to Test Class Object.
中,将在new Test();
内存区Heap
中创建一个新对象和您的方法
JVM
将使用 public void print() {
System.out.println("This is demo");
}
调用哪个是t.print()
(非静态),因此需要类实例才能调用Instance Method
方法。