V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
Newyorkcity
V2EX  ›  问与答

Java :是不是即使 Main 函数里什么也不做,在堆上也已经生成了一个主类的实例对象?能不能让引用变量指向这个对象?(用 this?)?谢谢

  •  
  •   Newyorkcity · 2018-03-25 11:33:48 +08:00 · 1681 次点击
    这是一个创建于 2195 天前的主题,其中的信息可能已经有所发展或是发生改变。

    第一个问题我觉得应该是对的吧,因为自己实际跑了一下如下代码

    package staticSuper;
    
    class StaticSuper {
    	static {
    		System.out.println("super static block");
    	}
    	StaticSuper(){
    		System.out.println("super constructor");
    	}
    }
    
    public class StaticTests extends StaticSuper {
    	static {
    		System.out.println("static block");
    	}
    	StaticTests(){
    		System.out.println("main class");
    	}
    	public static void main(String args[]) {
    //		System.out.println("in main");
    	}
    }
    

    结果是

    super static block
    static block
    

    之所以会问第二个问题,是因为继续学(初学者)看到一个简单的 GUI 程序代码是这样的

    package simpleGui2;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class SimpleGui2 implements ActionListener{
    	JButton button;
    	public static void main(String[] args) {
    		SimpleGui2 gui = new SimpleGui2();
    		gui.go();
    	}	
    	public void go() {
    		JFrame frame = new JFrame();
    		button  = new JButton();
    		
    		button.addActionListener(this);  //这个 this 传入的应该就是这个主类的实例对象吧?
    		
    		frame.getContentPane().add(button);
    		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		frame.setSize(300,300);
    		frame.setVisible(true);
    	}
    	public void actionPerformed(ActionEvent evnet) {
    		button.setText("I've been clicked!");
    	}
    }
    

    带注释的那一行里的 this 应该就是这个主类的实例对象吧?
    但我稍稍多想了一些,就有点疑惑,那就是既然有了这个因为是主类而必须产生在堆上的实例对象,那为什么有许多程序都还要在 main 方法里再 new 一个出来呢?为何不直接用 this 呢?
    JAVA 才初学,可能许多概念都还没学习到,望海涵..谢谢..

    7 条回复    2018-03-25 17:27:07 +08:00
    dobelee
        1
    dobelee  
       2018-03-25 11:46:01 +08:00 via Android   ❤️ 3
    大佬,main 是静态啊。
    zengmingyang96
        2
    zengmingyang96  
       2018-03-25 12:28:10 +08:00 via Android
    静态方法的调用会先初始化这个类



    没法调用非静态方法,所以 new
    lhx2008
        3
    lhx2008  
       2018-03-25 12:59:31 +08:00 via Android
    不 new,都用一个的话,那所有 Integer 都是一样的,所有 String 都是一样的,你用了 5 次,改了一个,其他四个也跟着改
    CodeingBoy
        4
    CodeingBoy  
       2018-03-25 17:16:09 +08:00   ❤️ 1
    运行 main 方法的时候相当于对静态成员产生了引用,这会要求 JVM 载入该类的 Class,然后进行初始化。于是你的 static 块还有 static 变量就会被执行和初始化。而类继承的时候,执行的初始化顺序是:基类构造器->基类成员的初始化->子类的构造器。所以基类的 static 块就会先于子类的被执行。
    所以第一个问题:即使 Main 函数里什么也不做,在堆上也已经生成了一个主类的*Class*对象,此时没有实例对象
    能不能让引用变量指向这个*Class*对象?使用 getClass()应该可以

    第二段代码的话,静态方法没有 this,也没有对应类的实例对象。当然是要 new 一个实例了。
    第二段代码中的 this 确实是实例对象,不过你要看到那个 go 是一个实例方法啊,当然会有一个 this 绑定在一起啊。
    CodeingBoy
        5
    CodeingBoy  
       2018-03-25 17:18:52 +08:00
    @CodeingBoy #4 要在 static 方法中引用变量指向这个*Class*对象,应该使用 Class 对象字面量 ClassName.Class
    Newyorkcity
        6
    Newyorkcity  
    OP
       2018-03-25 17:23:45 +08:00
    @CodeingBoy 谢谢!
    CodeingBoy
        7
    CodeingBoy  
       2018-03-25 17:27:07 +08:00
    @Newyorkcity #6 具体你可以阅读一下 Java 编程思想,这本书讲的比较详细。
    另外 Class 是否是在堆上(因为 JVM 内存还分了很多区,比如方法区等,不仅仅只有 Java 堆)放置的需要商榷,详细的信息你可以再查阅。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3323 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 13:28 · PVG 21:28 · LAX 06:28 · JFK 09:28
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.