首页 > 编程知识 正文

java在类中找不到main方法,java找不到符号怎么解决

时间:2023-05-05 23:48:18 阅读:166605 作者:2180

简介:我学了大约两年多的Java语言,但是最近当我需要使用命令行工具编译和运行Java程序时,我收到了一个错误。 花了很长时间,解决了这个问题,发现解决方法在初学Java的时候用过。 一是浪费不必要的时间,以免今后再次发生同样的问题; 二是作为使用该语言的程序员,对该语言的基本问题有清楚的理解和认识;三是网络上的一些解决方案还不够。 也有不说明问题的原因,直接给出答案的; 是的,没有列举一些常见情况的解决方案。 所以,写这篇文章,让读者举一反三,深入了解问题。

一.问题分析中找不到主类或无法加载。 主要原因有两个:

1 .类名错误

2 .类所在的位置未添加到类加载路径中

二、解决问题本部分针对“一”中提出的两个问题产生的原因,分别进行分析和处理。 以下是一些关于java问题处理的基本概念。

1 .类名错误完全限定类名: bzdbq类名。 此外,如果bzdbq为空,即代码不包含package语句,则类所在的包也称为缺省包

例如,以下代码的全限定类名为" com.gzn.demo.HelloWorld "

//文件名hello world.javapackagecom.gzn.demo; public class hello world { publicstaticvoidmain (string args [ ] ) system.out.println(Helloworld ' ); 运行java程序时,完全限定的类名唯一标识文件。 与文件系统中的路径(等效的bzdbq (文件名)等效的类名)唯一标识文件相同。 本质上,bzdbq与文件系统中的目录作用相同,有助于避免文件分隔中的重复名称。

存在Java如何识别类文件的bzdbq的问题。

实际上,bzdbq的识别是通过文件系统目录实现的。 例如,上述bzdbq是“com.gzn.demo”的HelloWorld.java文件,文件系统中的位置为“comgzndemo”,是编译后的hello world.clo

在Windows操作系统的命令行中,执行Java代码的语法如下: Java命令位于目录com的更高目录中(通常为项目的目录名称)。 类名不能包含扩展名. class :

Java完全限定类名

例如java com.gzn.demo.HelloWorld; 如果bzdbq为空,则为java HelloWorld

Windows操作系统还有另一种语法格式。 (其他系统不一定能做到。 )很少使用。 用反斜杠代替圆点很好。 我个人推测,不使用斜线是为了与系统的文件分隔符相区别:

例如Java com/gzn/demo/HelloWorld; 如果bzdbq为空,则为java HelloWorld

可能会发生错误。 在命令行中运行java程序时,类名中会包含扩展名

在helloworld项目目录下运行java命令。 HelloWorld.class文件位于comgzndemo目录下。 也就是说,bzdbq是com.gzn.demo。 这里不说明。

c :usersgznhelloworldjavacom.gzn.demo.hello world.class

或bzdbq为空

c :usersgznhelloworldjavahelloworld.class

上述格式不会对java程序的语法格式进行编码,因此会发生错误。 java可能会将" HelloWorld.class "作为整体类名,要搜索的文件可能是" HelloWorld.class ",显然找不到。

可能发生错误的情况2 :未指定完全限定类名的bzdbq部分或指定了bzdbq,但Java命令未正确执行

假设HelloWorld.class,bzdbq是com.gzn.demo,位置是: c :usersgzn hello world com gzn demo

执行以下命令

c :usersgznhello worldcomgzndemojavahelloworld

运行命令时,在当前目录下查找并阅读此文件后,您发现该类为" com.gzn.demo.HelloWorld "。 (完全限定类名唯一标识类。 在上述内容中进行了说明。 )找不到要执行的类,因为它与要执行的类" HelloWorld "不是同一类。

因此,一个自然的想法是执行以下命令

c :usersgznhello worldcomgzndemojavacom.gzn.demo.hello world

bzdbq和文件名是一对一映射的。 如上所述,运行命令时,从命令所在的位置开始,查找" comgzndemo"路径下的Hell

oWorld文件。由于“C:Usersgznhelloworldcomgzndemo”路径下根本不存在目录“com”(更不用说gzndemo),因此,找不到运行的类。

正确的运行命令的方法,呼之欲出,只需改变命令的运行位置即可,如下所示
C:Usersgznhelloworld>java com.gzn.demo.HelloWorld
运行命令后,会在“comgzndemo”路径下找到并读取HelloWorld文件,发现该类的全限定名为“com.gzn.demo.HelloWorld”,查找的类正是Java想要运行的类。


以上是比较初级的出错情况,下文将要介绍相对比较高级的出错情况,这也是其他博文未曾给出解决方案的情况。同时还会介绍classpath的概念,及使用方法。加油! 2. 类所在位置未添加至类加载路径中

类加载路径(Classpath):火星上的电话的程序依赖第三方或者自己写的类文件时,需要指出上述文件的所在位置,即类加载路径。Java虚拟机的类加载器会在你指定的路径中,查找你的程序所依赖的类文件(依赖的类文件 在import语句中指定)

classpath可以通过以下两种方式指定:

方式一:配置环境变量

  这种方式是初学Java者肯定了解的方式,通常在下载完JDK后就会进行配置。然而在JDK1.5之后,官方已不建议使用这种方式来指定类加载路径,原因后文扩展部分会谈及。


说明:“.”表示在当前目录,即java等命令运行时所在目录;
dt.jar是关于运行环境的类库,主要是用于swing的包,如果不使用可以不配置;
tools.jar是工具类库,它在编译和运行一个类时被使用

方式二:java命令的-cp(或-classpath)参数指定(官方建议)

这种方式是JDK1.5后官方建议的方式。火星上的电话在命令行下运行java命令时,如果没有指定-classpath参数,那么默认使用环境变量中设置的ClASSPATH。官方建议,你在运行每个程序时,为其显示设置所依赖的类文件所在的位置,而不是使用“全局”性质的环境变量中CLASSPATH。一旦你运行程序时指定了-classpath参数,环境变量中的CLASSPATH就不会在使用,而是使用你参数的classpath。实际上,JDK1.5以后,官方已经不建议配置CLASSPATH环境变量。

语法格式如下:

java -cp <路径1;路径2;…> 全限定类名

路径:依赖的文件所在的绝对路径(或相对路径),如果类文件在jar包中,路径后还要写上jar包的名字,例如“C:usersgznmylibalgs4.jar”
注意,“.”代表当前路径,即java命令运行时所在路径。

可能出错情况三 :存在依赖外部jar包时,命令行运行java命令,classpath参数中只是添加了外部jar包路径,没有添加当前目录“.”,导致要运行的类文件找不到。

或者,程序在IDE(eclipse、IDEA等)开发工具中可以运行,但是在命令行下不能运行,情况相同。

在某篇高赞博文中,依然存在的问题

下面,通过问题在现的方式,讲解解决方法。
项目简介:HelloWorld.java程序,位置“C:Usersgznhelloworldcomgzndemo”,依赖algs4.jar(位置C:Usersgznhelloworld)中的edu.princeton.cs.algs4.StdOut类,调用了该类的print函数,其API如下

public class StdOut
public static void print(String s); 打印输出指定的字符串

HelloWorld.java

package com.gzn.demo;import edu.princeton.cs.algs4.StdOut;public class HelloWorld {public static void main(String args[]) {StdOut.print("Hello World!");}}

项目结构如下图所示:

在命令行运行程序时,存在外部依赖,不仅要在-cp (或-classpath)中指明依赖的路径,还有把当前路径加进去。因为火星上的电话指定了-classpath参数后,环境变量失效,于是环境变量CLASSPATHY中设置的当前目录“.”也就不能用了。虚拟机类加载器加载类的路径只能在classpath类加载路径指明的位置中查找,如果路径中没有添加当前目录“.”,也就是当前要运行的类所在位置没有添加到类加载路径中,显然会查找不到类。解决方法如下图所示:

三、扩展知识 1. JDK目录结构及环境变量介绍

JDK目录介绍

初学者环境变量配置如下:

变量名值CLASSPATH.;%JAVA_HOME%libdt.jar;%JAVA_HOME%libtool.jar (注,jdk1.5后无需配置)JAVA_HOMED:jdk8(JDK安装目录,视个人安装情况而定)Path%JAVA_HOME%开朗的帽子;%JAVA_HOME%jre开朗的帽子

Path为命令行工具指定命令的查找路径。命令的本质是可执行程序,设置后可以在命令行工具下运行java、javac、javah等常用的命令;
JAVA_HOME 指定了JDK(Java开发工具包)路径。设置后,无论是编译还是运行程序,类加载器都会从相应的目录中加载需要的类库。如运行javac编译命令,会从”%JAVA_HOME%libtool.jar”加载需要的类;通过java命令运行程序,会从“%JAVA_HOME%jrelibrt.jar”加载程序依赖的类;Java虚拟机会从“%JAVA_HOME%jrelibext”加载依赖的类。

jdk中的函数库lib称为Java的标准库,指定了JAVA_HOME环境变量后就可以使用了,编译和运行会自动在相应位置查找依赖的类。而第三方库(如mysql-connector-java-5.1.40.jar)和用户自己定义的类库 在编译和运行时,需要在-cp类加载路径参数中指明库的位置。

2. 为什么jdk1.5后不需要配置环境变量了?

此部分内容参考自Java开发环境不再需要配置classpath!

在JDK1.5之前,是没有办法在当前目录下加载类的(找不到 JDK目录下lib文件夹中的.jar文件),所以我们需要通过配置classpath,但JDK1.5之后,JRE能自动搜索目录下类文件,并且加载dt.jar和tool.jar的类。

The class path tells the JDK tools and applications where to find third-party and user-defined classes that are not extensions or part of the Java platform. See The Extension Mechanism at
类路径告诉JDK工具和应用程序在哪里可以找到第三方和用户定义的类,这些类既不是Java平台的扩展,也不是Java平台的一部分。参见扩展机制

If you upgrade from an earlier release of the JDK, then your startup settings might include CLASSPATH settings that are no longer needed. You should remove any settings that are not application-specific, such as classes.zip. Some third-party applications that use the Java Virtual Machine (JVM) can modify your CLASSPATH environment variable to include the libraries they use. Such settings can remain.

如果您从JDK的早期版本升级,那么您的启动设置可能包括不再需要的类路径设置。您应该删除任何与应用程序无关的设置,比如classes.zip。一些使用Java虚拟机(JVM)的第三方应用程序可以修改类路径环境变量,以包含它们使用的库。这样的设置可以保留。

You can change the class path by using the -classpath or -cp option of some Java commands when you call the JVM or other JDK tools or by using the CLASSPATH environment variable. See JDK Commands Class Path Options. Using the -classpath option is preferred over setting the CLASSPATH environment variable because you can set it individually for each application without affecting other applications and without other applications modifying its value. See CLASSPATH Environment Variable.

在调用JVM或其他JDK工具时,可以使用一些Java命令的-classpath或-cp选项,或者使用CLASSPATH环境变量,来更改类路径。参见JDK命令类路径选项。使用-classpath选项优于设置CLASSPATH环境变量,因为您可以为每个应用程序单独设置它,而不影响其他应用程序,也不需要其他应用程序修改它的值。参见CLASSPATH环境变量。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。