问题描述
类是在其任何static成员被访问时加载的。我一开始理解的就是试图访问main()(一个static方法),于是加载器开始启动并找出该类的编译代码(在同名class文件之中)。可是有这样一种情况:当运行程序一遍后,注释掉main(),然后再运行程序,会发现似乎加载过程同样发生了:静态变量进行了初始化,然后抛出异常java.lang.NoSuchMethodError:main。当然,这应该是假象。因为这种情况的前提是运行程序一遍后,注释掉main()。而在正常情况下,没有main(),程序根本是无法运行的。谁能告诉这种情况的原因是什么?PS:我用的开发工具是eclipse。
解决方案
解决方案二:
“类是在其任何static成员被访问时加载的”这句话是错的,不知你从哪里听来的。应该说:“如果一个类还没有被加载,那么它会在其任何static成员被访问时加载”。访问static成员确实是加载类的一种方式,但绝不是唯一方式。当你试图用"java<类名>"的方式来启动一个程序时,JVM会首先加载该类,再试图在其中寻找main()方法。
解决方案三:
类是在其任何static成员被访问时加载的哪里听来的??只能说static成员是在类被加载的时候加载还有main只是程序入口,并不是类加载时机main本身只是一个方法,如果类没有被加载,此方法何来运行之说?
解决方案四:
引用1楼dan1980的回复:
“类是在其任何static成员被访问时加载的”这句话是错的,不知你从哪里听来的。应该说:“如果一个类还没有被加载,那么它会在其任何static成员被访问时加载”。访问static成员确实是加载类的一种方式,但绝不是唯一方式。当你试图用"java<类名>"的方式来启动一个程序时,JVM会首先加载该类,再试图在其中寻找main()方法。
“类是在其任何static成员被访问时加载的”这句原话出自ThinkingInJava4th。再看看原文中说的:在Beetle上运行Java时,所发生的第一件事情就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件中)。……我迷惑了。dan1980兄能介绍一下加载类的不同方式吗?先谢过了。
解决方案五:
引用2楼beiouwolf的回复:
类是在其任何static成员被访问时加载的哪里听来的??只能说static成员是在类被加载的时候加载还有main只是程序入口,并不是类加载时机main本身只是一个方法,如果类没有被加载,此方法何来运行之说?
我对类加载的开始还是比较雾水的。的确,如果类没有加载,main()如何运行?但是我的问题是:注释掉main()方法,为什么会出现静态变量的加载,然后是异常java.lang.NoSuchMethodError:main。也许这些假象都是JVM在作祟。
解决方案六:
引用3楼tequliapop的回复:
引用1楼dan1980的回复:“类是在其任何static成员被访问时加载的”这句话是错的,不知你从哪里听来的。应该说:“如果一个类还没有被加载,那么它会在其任何static成员被访问时加载”。访问static成员确实是加载类的一种方式,但绝不是唯一方式。当你试图用"java<类名>"的方式来启动一个程序时,JVM会首先加载该类,再试图在其中寻找main()方法。“类是在其任何static成员被访问时加载的”这句原话出自ThinkingInJava4th。再看看原文中说的:在Beetle上运行Java时,所发生的第一件事情就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件中)。……我迷惑了。dan1980兄能介绍一下加载类的不同方式吗?先谢过了。
我相信ThinkingInJava上没有这句话,请指出具体章节,我回头去查。造成类被加载的情况太多了,最简单的:创建一个类的对象就必须先加载该类;另外,超类在其派生类被加载之前自动加载;主程序对应的类由JVM自动加载(当然也包括它的所有超类);运行Applet时,Applet类(以及它的所有超类)也是JVM自动加载的。JVM第一次启动时还会加载很多所需的类,只不过它们都在后台运行,你不察觉罢了。程序员还可以手动加载类,使用Class.forName()方法。不管类以何种方式加载,有一点是肯定的:访问类的成员一定是发生是类加载之后的。每个类都只加载一次,而且类的加载是系统行为,你通常无法控制。系统会保证你在使用任何一个类之前它已经成功加载。所以,“类是在其任何static成员被访问时加载的”或许应该说成“类是在其任何static成员被访问之前加载的”,而且,不总是在紧接着的之前。因为类只加载一次,访问static成员时,它很可能早就加载完毕了(从而不再被加载),也或许它还没有被加载,于是系统先加载类,加载完毕后再返回你要访问的成员。
解决方案七:
恩,学到了东西
解决方案八:
没看明白是什么。呵呵。
解决方案九:
学习了!
解决方案十:
只有在类首次被主动使用时就会加载,静态方法,静态字段被首次条用,反射,序列化等等一共六种
解决方案十一:
引用5楼dan1980的回复:
引用3楼tequliapop的回复:引用1楼dan1980的回复:“类是在其任何static成员被访问时加载的”这句话是错的,不知你从哪里听来的。应该说:“如果一个类还没有被加载,那么它会在其任何static成员被访问时加载”。访问static成员确实是加载类的一种方式,但绝不是唯一方式。当你试图用"java <类名>"的方式来启动一个程序时,JVM会首先加载该类,再试图在其中寻找main()方法。“类是在其任何static成员被访问时加载的”这句原话出自ThinkingInJava4th。再看看原文中说的:在Beetle上运行Java时,所发生的第一件事情就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件中)。……我迷惑了。dan1980兄能介绍一下加载类的不同方式吗?先谢过了。我相信ThinkingInJava上没有这句话,请指出具体章节,我回头去查。造成类被加载的情况太多了,最简单的:创建一个类的对象就必须先加载该类;另外,超类在其派生类被加载之前自动加载;主程序对应的类由JVM自动加载(当然也包括它的所有超类);运行Applet时,Applet类(以及它的所有超类)也是JVM自动加载的。JVM第一次启动时还会加载很多所需的类,只不过它们都在后台运行,你不察觉罢了。程序员还可以手动加载类,使用Class.forName()方法。不管类以何种方式加载,有一点是肯定的:访问类的成员一定是发生是类加载之后的。每个类都只加载一次,而且类的加载是系统行为,你通常无法控制。系统会保证你在使用任何一个类之前它已经成功加载。所以,“类是在其任何static成员被访问时加载的”或许应该说成“类是在其任何static成员被访问之前加载的”,而且,不总是在紧接着的之前。因为类只加载一次,访问static成员时,它很可能早就加载完毕了(从而不再被加载),也或许它还没有被加载,于是系统先加载类,加载完毕后再返回你要访问的成员。
原话出自Thinginginjava4thP146的注解。我自己还得想想。
解决方案十二:
引用5楼dan1980的回复:
引用3楼tequliapop的回复:引用1楼dan1980的回复:“类是在其任何static成员被访问时加载的”这句话是错的,不知你从哪里听来的。应该说:“如果一个类还没有被加载,那么它会在其任何static成员被访问时加载”。访问static成员确实是加载类的一种方式,但绝不是唯一方式。当你试图用"java <类名>"的方式来启动一个程序时,JVM会首先加载该类,再试图在其中寻找main()方法。“类是在其任何static成员被访问时加载的”这句原话出自ThinkingInJava4th。再看看原文中说的:在Beetle上运行Java时,所发生的第一件事情就是试图访问Beetle.main()(一个static方法),于是加载器开始启动并找出Beetle类的编译代码(在名为Beetle.class的文件中)。……我迷惑了。dan1980兄能介绍一下加载类的不同方式吗?先谢过了。我相信ThinkingInJava上没有这句话,请指出具体章节,我回头去查。造成类被加载的情况太多了,最简单的:创建一个类的对象就必须先加载该类;另外,超类在其派生类被加载之前自动加载;主程序对应的类由JVM自动加载(当然也包括它的所有超类);运行Applet时,Applet类(以及它的所有超类)也是JVM自动加载的。JVM第一次启动时还会加载很多所需的类,只不过它们都在后台运行,你不察觉罢了。程序员还可以手动加载类,使用Class.forName()方法。不管类以何种方式加载,有一点是肯定的:访问类的成员一定是发生是类加载之后的。每个类都只加载一次,而且类的加载是系统行为,你通常无法控制。系统会保证你在使用任何一个类之前它已经成功加载。所以,“类是在其任何static成员被访问时加载的”或许应该说成“类是在其任何static成员被访问之前加载的”,而且,不总是在紧接着的之前。因为类只加载一次,访问static成员时,它很可能早就加载完毕了(从而不再被加载),也或许它还没有被加载,于是系统先加载类,加载完毕后再返回你要访问的成员。
5楼正解.楼主你找不到main方法是因为你调用的启动类必须含有main方法。与类加载机制没有关系。
解决方案十三:
main方法是java程序的入口方法,没有的话,当然不能运行了~~~