欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的解決方法

 更新時間:2022年01月25日 11:22:42   作者:明月幾時有666  
這篇文章主要給大家介紹了關(guān)于Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的解決方法,文中通過實(shí)例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下

前言:

雖然學(xué)習(xí)Java語言約有兩年多,但在最近需要使用命令行工具編譯并運(yùn)行Java程序時,還是報錯了?;ㄙM(fèi)了一些時間,解決了該問題,發(fā)現(xiàn)解決方法在初學(xué)Java時使用過。一則,為了避免以后再出現(xiàn)同樣的問題而浪費(fèi)不必要的時間;二則,作為使用該語言的程序員,對于該語言的一些基本問題,應(yīng)該有清晰的理解和認(rèn)識;三則,網(wǎng)上的一些解決方案,不夠完備。有的沒有解釋問題原因,直接給出答案;有的,未列舉出某些常見情況的解決方案。因此,寫此文章,讓讀者可以舉一反三,深入理解問題。

一、 問題分析

找不到或無法加載主類,主要原因有兩個:

1. 類名錯誤

2. 類所在位置未添加至類加載路徑中

二、 問題解決

本部分將針對在“一”中提出的兩個問題發(fā)生原因,分別進(jìn)行分析及處理。并且會介紹java的一些和處理問題相關(guān)的基本概念。

1. 類名錯誤

全限定類名:包名+類名。另外,當(dāng)包名為空時(即代碼不包含package語句),稱類所在包為默認(rèn)包

例如,以下代碼的全限定類名為:“com.gzn.demo.HelloWorld”

// 文件名HelloWorld.java
package com.gzn.demo;
public class HelloWorld {
    public static void main(String args[]) {
        System.out.println("hello world");
    }
}

在運(yùn)行java程序時,全限定類名可以唯一確定該文件,就像是文件系統(tǒng)中路徑(相當(dāng)包名)+文件名(相當(dāng)類名)可以唯一確定一個文件一樣。本質(zhì)上包名發(fā)揮的作用和文件系統(tǒng)中的目錄相同,有利于文件分隔避免重名。

現(xiàn)在存在一個問題,Java是如何識別一個類文件的包名的?

實(shí)際上,包名的識別是通過文件系統(tǒng)的目錄實(shí)現(xiàn)的 。例如,上文提到的包名為“com.gzn.demo”的HelloWorld.java文件,該文件在文件系統(tǒng)中的位置為 “com\gzn\demo”,編譯后的HelloWorld.class也在"com\gzn\demo"目錄下,因此,在運(yùn)行java程序后加載類時,只需在“com\gzn\demo”目錄下,查看是否存在要查找的文件即可。簡而言之,目錄(或路徑)名于包名存在一一映射的關(guān)系,可認(rèn)為相等。

在Windows操作系統(tǒng)的命令行下,運(yùn)行Java代碼的語法格式為,注意,此時java命令位于目錄com的上一級目錄(一般為項目的目錄名);類名不能包含擴(kuò)展名.class

Java 全限定類名
例如java com.gzn.demo.HelloWorld;包名為空則為java HelloWorld

Windows操作系統(tǒng)中還有另一種語法格式(其他系統(tǒng)未必可以),不常用,使用反斜杠代替了點(diǎn)好,之所以沒用正斜杠,個人猜測是為了和系統(tǒng)的文件分隔符進(jìn)行區(qū)分:

例如Java com/gzn/demo/HelloWorld; 包名為空則為java HelloWorld

可能出錯情況一 :在命令行運(yùn)行java程序時,類名包含了擴(kuò)展名

在helloworld項目目錄下運(yùn)行java命令,HelloWorld.class文件在“com\gzn\demo”目錄下,即包名為com.gzn.demo,上文已介紹,不在贅述。
C:\Users\gzn\helloworld>java com.gzn.demo.HelloWorld.class

或者包名為空
C:\Users\gzn\helloworld> java HelloWorld.class
上述寫法,會出現(xiàn)報錯,原因是它不符號java運(yùn)行程序的語法格式,java可能把“HelloWorld.class”作為一個整體類名處理,那么要查找的文件可能是“HelloWorld.class.class”,顯然是找不到的。

可能出錯情況二 :運(yùn)行Java命令時未指明全限定類名的包名部分或指明了包名但Java命令運(yùn)行的位置不正確

假設(shè)HelloWorld.class,包名為com.gzn.demo,所在位置為: C:\Users\gzn\helloworld\com\gzn\demo

運(yùn)行以下命令
C:\Users\gzn\helloworld\com\gzn\demo>java HelloWorld
運(yùn)行命令后,會在當(dāng)前目錄下,查找并讀取該文件后,發(fā)現(xiàn)該類為“com.gzn.demo.HelloWorld”(全限定類名唯一確定一個類,上文已介紹)與我要運(yùn)行的類“HelloWorld”并不是同一類,因此,找不到要運(yùn)行的類。

于是,很自然的一個想法是運(yùn)行以下命令
C:\Users\gzn\helloworld\com\gzn\demo>java com.gzn.demo.HelloWorld
包名和文件名是一一映射的(上文已介紹),運(yùn)行命令后,會從命令所在位置開始(即以命令所在位置為相對路徑),查找“com\gzn\demo\”路徑下的HelloWorld文件。由于“C:\Users\gzn\helloworld\com\gzn\demo”路徑下根本不存在目錄“com”(更不用說gzn\demo),因此,找不到運(yùn)行的類。

正確的運(yùn)行命令的方法,呼之欲出,只需改變命令的運(yùn)行位置即可,如下所示
C:\Users\gzn\helloworld>java com.gzn.demo.HelloWorld
運(yùn)行命令后,會在“com\gzn\demo”路徑下找到并讀取HelloWorld文件,發(fā)現(xiàn)該類的全限定名為“com.gzn.demo.HelloWorld”,查找的類正是Java想要運(yùn)行的類。

以上是比較初級的出錯情況,下文將要介紹相對比較高級的出錯情況,這也是其他博文未曾給出解決方案的情況。同時還會介紹classpath的概念,及使用方法。加油!

2. 類所在位置未添加至類加載路徑中

類加載路徑(Classpath):當(dāng)你的程序依賴第三方或者自己寫的類文件時,需要指出上述文件的所在位置,即類加載路徑。Java虛擬機(jī)的類加載器會在你指定的路徑中,查找你的程序所依賴的類文件(依賴的類文件 在import語句中指定)

classpath可以通過以下兩種方式指定:

方式一:配置環(huán)境變量

  這種方式是初學(xué)Java者肯定了解的方式,通常在下載完JDK后就會進(jìn)行配置。然而在JDK1.5之后,官方已不建議使用這種方式來指定類加載路徑,原因后文擴(kuò)展部分會談及。

說明:“.”表示在當(dāng)前目錄,即java等命令運(yùn)行時所在目錄;

dt.jar是關(guān)于運(yùn)行環(huán)境的類庫,主要是用于swing的包,如果不使用可以不配置;

tools.jar是工具類庫,它在編譯和運(yùn)行一個類時被使用

方式二:java命令的-cp(或-classpath)參數(shù)指定(官方建議)

這種方式是JDK1.5后官方建議的方式。當(dāng)你在命令行下運(yùn)行java命令時,如果沒有指定-classpath參數(shù),那么默認(rèn)使用環(huán)境變量中設(shè)置的ClASSPATH。官方建議,你在運(yùn)行每個程序時,為其顯示設(shè)置所依賴的類文件所在的位置,而不是使用“全局”性質(zhì)的環(huán)境變量中CLASSPATH。一旦你運(yùn)行程序時指定了-classpath參數(shù),環(huán)境變量中的CLASSPATH就不會在使用,而是使用你參數(shù)的classpath。實(shí)際上,JDK1.5以后,官方已經(jīng)不建議配置CLASSPATH環(huán)境變量。

語法格式如下:

java -cp <路徑1;路徑2;…> 全限定類名

路徑:依賴的文件所在的絕對路徑(或相對路徑),如果類文件在jar包中,路徑后還要寫上jar包的名字,例如“C:\users\gzn\mylib\algs4.jar”
注意,“.”代表當(dāng)前路徑,即java命令運(yùn)行時所在路徑。

可能出錯情況三 :存在依賴外部jar包時,命令行運(yùn)行java命令,classpath參數(shù)中只是添加了外部jar包路徑,沒有添加當(dāng)前目錄“.”,導(dǎo)致要運(yùn)行的類文件找不到。

或者,程序在IDE(eclipse、IDEA等)開發(fā)工具中可以運(yùn)行,但是在命令行下不能運(yùn)行,情況相同。

在某篇高贊博文中,依然存在的問題

下面,通過問題在現(xiàn)的方式,講解解決方法。

項目簡介:HelloWorld.java程序,位置“C:\Users\gzn\helloworld\com\gzn\demo”,依賴algs4.jar(位置C:\Users\gzn\helloworld)中的edu.princeton.cs.algs4.StdOut類,調(diào)用了該類的print函數(shù),其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!");
	}
}

項目結(jié)構(gòu)如下圖所示:

在命令行運(yùn)行程序時,存在外部依賴,不僅要在-cp (或-classpath)中指明依賴的路徑,還有把當(dāng)前路徑加進(jìn)去。因為當(dāng)你指定了-classpath參數(shù)后,環(huán)境變量失效,于是環(huán)境變量CLASSPATHY中設(shè)置的當(dāng)前目錄“.”也就不能用了。虛擬機(jī)類加載器加載類的路徑只能在classpath類加載路徑指明的位置中查找,如果路徑中沒有添加當(dāng)前目錄“.”,也就是當(dāng)前要運(yùn)行的類所在位置沒有添加到類加載路徑中,顯然會查找不到類。解決方法如下圖所示:

三、擴(kuò)展知識

1. JDK目錄結(jié)構(gòu)及環(huán)境變量介紹

JDK目錄介紹

初學(xué)者環(huán)境變量配置如下:

變量名
CLASSPATH.;%JAVA_HOME%\lib\dt.jar;%JAVA_HOME%\lib\tool.jar (注,jdk1.5后無需配置)
JAVA_HOMED:\jdk8(JDK安裝目錄,視個人安裝情況而定)
Path%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin

Path為命令行工具指定命令的查找路徑。命令的本質(zhì)是可執(zhí)行程序,設(shè)置后可以在命令行工具下運(yùn)行java、javac、javah等常用的命令;
JAVA_HOME 指定了JDK(Java開發(fā)工具包)路徑。設(shè)置后,無論是編譯還是運(yùn)行程序,類加載器都會從相應(yīng)的目錄中加載需要的類庫。如運(yùn)行javac編譯命令,會從”%JAVA_HOME%\lib\tool.jar”加載需要的類;通過java命令運(yùn)行程序,會從“%JAVA_HOME%\jre\lib\rt.jar”加載程序依賴的類;Java虛擬機(jī)會從“%JAVA_HOME%\jre\lib\ext\”加載依賴的類。

jdk中的函數(shù)庫lib稱為Java的標(biāo)準(zhǔn)庫,指定了JAVA_HOME環(huán)境變量后就可以使用了,編譯和運(yùn)行會自動在相應(yīng)位置查找依賴的類。而第三方庫(如mysql-connector-java-5.1.40.jar)和用戶自己定義的類庫 在編譯和運(yùn)行時,需要在-cp類加載路徑參數(shù)中指明庫的位置。

2. 為什么jdk1.5后不需要配置環(huán)境變量了?

此部分內(nèi)容參考自Java開發(fā)環(huán)境不再需要配置classpath

在JDK1.5之前,是沒有辦法在當(dāng)前目錄下加載類的(找不到 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工具和應(yīng)用程序在哪里可以找到第三方和用戶定義的類,這些類既不是Java平臺的擴(kuò)展,也不是Java平臺的一部分。參見擴(kuò)展機(jī)制

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的早期版本升級,那么您的啟動設(shè)置可能包括不再需要的類路徑設(shè)置。您應(yīng)該刪除任何與應(yīng)用程序無關(guān)的設(shè)置,比如classes.zip。一些使用Java虛擬機(jī)(JVM)的第三方應(yīng)用程序可以修改類路徑環(huán)境變量,以包含它們使用的庫。這樣的設(shè)置可以保留。

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.

在調(diào)用JVM或其他JDK工具時,可以使用一些Java命令的-classpath或-cp選項,或者使用CLASSPATH環(huán)境變量,來更改類路徑。參見JDK命令類路徑選項。使用-classpath選項優(yōu)于設(shè)置CLASSPATH環(huán)境變量,因為您可以為每個應(yīng)用程序單獨(dú)設(shè)置它,而不影響其他應(yīng)用程序,也不需要其他應(yīng)用程序修改它的值。參見CLASSPATH環(huán)境變量。

Java開發(fā)環(huán)境不再需要配置classpath!

總結(jié) 

到此這篇關(guān)于Java命令行運(yùn)行錯誤之找不到或無法加載主類問題的文章就介紹到這了,更多相關(guān)Java找不到或無法加載主類內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Mybatis 插件原理解析

    Mybatis 插件原理解析

    mybatis是一款優(yōu)秀的ORM開源框架,這個框架具有極強(qiáng)的靈活性,本文再次給大家介紹Mybatis 插件原理,感興趣的朋友一起看看吧
    2021-10-10
  • Java基礎(chǔ)知識精通各種運(yùn)算符

    Java基礎(chǔ)知識精通各種運(yùn)算符

    計算機(jī)的最基本用途之一就是執(zhí)行數(shù)學(xué)運(yùn)算,作為一門計算機(jī)語言,Java也提供了一套豐富的運(yùn)算符來操縱變量,本篇對大家的學(xué)習(xí)或工作具有一定的價值,需要的朋友可以參考下
    2022-04-04
  • Java 梳理總結(jié)關(guān)于static關(guān)鍵字常見問題

    Java 梳理總結(jié)關(guān)于static關(guān)鍵字常見問題

    static關(guān)鍵字基本概念我們可以一句話來概括:方便在沒有創(chuàng)建對象的情況下來進(jìn)行調(diào)用。也就是說:被static關(guān)鍵字修飾的不需要創(chuàng)建對象去調(diào)用,直接根據(jù)類名就可以去訪問,讓我們來了解一下你可能還不知道情況
    2022-04-04
  • idea激活A(yù)ctivateJrebel熱部署的方法詳解

    idea激活A(yù)ctivateJrebel熱部署的方法詳解

    這篇文章主要介紹了idea激活A(yù)ctivateJrebel熱部署的方法,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-11-11
  • 總結(jié)十個實(shí)用但偏執(zhí)的Java編程技術(shù)

    總結(jié)十個實(shí)用但偏執(zhí)的Java編程技術(shù)

    Java是世界上最流行的程序語言,從1995年問世以來,Java的生態(tài)系統(tǒng)在一直在蓬勃的發(fā)展著。下面這篇文章主要總結(jié)了十個實(shí)用但偏執(zhí)的Java編程技術(shù),需要的朋友可以參考借鑒,下面來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-01-01
  • Java實(shí)現(xiàn)合并多個升序鏈表

    Java實(shí)現(xiàn)合并多個升序鏈表

    本文主要介紹了Java實(shí)現(xiàn)合并多個升序鏈表,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2023-04-04
  • springboot 默認(rèn)靜態(tài)路徑實(shí)例解析

    springboot 默認(rèn)靜態(tài)路徑實(shí)例解析

    這篇文章主要介紹了springboot 默認(rèn)靜態(tài)路徑實(shí)例解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11
  • 關(guān)于HashSet與HashMap的區(qū)別及說明

    關(guān)于HashSet與HashMap的區(qū)別及說明

    這篇文章主要介紹了關(guān)于HashSet與HashMap的區(qū)別及說明,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • Java多線程join方法實(shí)例代碼

    Java多線程join方法實(shí)例代碼

    這篇文章主要介紹了Java多線程join方法實(shí)例代碼,分享了相關(guān)代碼示例,小編覺得還是挺不錯的,具有一定借鑒價值,需要的朋友可以參考下
    2018-02-02
  • VSCode?配置?Spring?Boot?項目開發(fā)環(huán)境的全過程

    VSCode?配置?Spring?Boot?項目開發(fā)環(huán)境的全過程

    兩三年前曾經(jīng)試過配置Java環(huán)境, 存在不少問題作罷. 最近搜了下相關(guān)的文章, 感覺VSCode對Java項目的支持比三年前完善了不少. 今天實(shí)際配置了一下環(huán)境, 把自己常用的功能過了一遍, 基本能跑通開發(fā)流程, 做個筆記,需要的朋友可以參考下
    2024-03-03

最新評論