当我们给JDK配置了path环境变量后我们就可以在任意目录下使用javac来编译我们当前目录下的源文件,而不需要在java的bin目录下进行编译。
如图,我们在桌面创建一个demo文件夹,里面放置一个名为A.java
的源文件.
里面的内容是:
直接使用javac命令编译A.java源文件:
不报错,编译成功:
运行时,使用java命令:
会出现错误:
找不到或无法加载主类
原因是这个Java文件是带有包的,我们必须指定它的权限定名
并且,还需带有-cp参数,
在之,还需要带有全路径:
格式:
java -cp 全路径 包名.类名
但是,你这样运行,还是报错:
简直了。
原因很简单,包名是com.github.app
那么,你也得创建一个这样的目录结构:
(当然如果是 IDE,它会帮我们自动生成这样的目录结构)
重新编译A.java
然后运行:
终于运行成功了。
很显然这样写会显得十分麻烦。不仅需要自己创建一系列层级目录,还需要指定一个路径。
我们先一个一个解决。
路径可以不指定,只要进入到那个外层目录就行了。
这里我们使用cd命令,直接进入桌面上的demo文件夹。
然后,其实就可以使用java命令执行.class文件了。
当然全限类名肯定是必不可少的:
java com.github.app.A
然后,我们解决需要创建多层级文件夹这样的麻烦问题。
很简单,只需要在编译时,添加一个参数 -d,然后指定生成的class文件存放的路径即可。
javac -d . A.java
-d表示生成与包名一致的目录
. 表示在当前目录下生成
这样它编译的时候会自动生成与包名一致的目录结构,非常的方便快捷。
再举一个例子,例如现在编译桌面上这样一个类,它没有放置在文件夹里而是直接放在了桌面上:
package com.briup.test;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet("/hello-world")
public class HelloWorld extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws
ServletException, IOException {
resp.setContentType("text/html");
PrintWriter out = resp.getWriter();
out.println("<html>");
out.println("<head>");
out.println("<title>index</title>");
out.println("</head>");
out.println("<body>");
out.println("<h1>Hello World! maven web</h1>");
out.println("</body>");
out.println("</html>");
}
}
如果使用命令:javac -d . HelloWorld.java
编译会报错,因为这个java类需要依赖其他第三方的类(javax.servlet.*),这些类jdk中没有提供。
所以需要使用这个命令:
javac -cp D:\Tomcat\apache-tomcat-8.5.58\lib\servlet-api.jar -d . HelloWorld.java
前面用-cp 指定classpath环境,即当前程序运行所需的环境。这样就可以编译成功。
其实前面的努力为为后来的运行成功打下了基础。
这里借用爱迪生的一句名言:
Thomas Edison,the famous inventor,once said "I’ve not failed. I’ve just found 10000 ways that won’t work."伟大的发明家托马斯·爱迪生说过,“我从未失败过。我只是发现了一万条行不通的路。”