java编程思想学习笔记(6)--手动创建、编译、运行Java程序

看到第六章的包这部分的内容,当自己创建,并手动编译、运行Java程序时遇到了一些问题

  1. 对于单个java源程序,没有引用其他的类时,可以直接在类所在的目录下进行编译运行。

    • 先来看一个简单程序:
    //当前目录为C:/Users/lzy/Desktop/package2
    // package package2;
    public class Main{
        public static void main(String args[]){
            System.out.println("Hello Java");
        }
    }
    • 通过命令行来编译、运行,结果如下:

      其中,-cp/-classpath 用于指定类路径,Java解释器会通过-cp指定的classpath来寻找.class文件,“.”表示当前路径(”..”表示上一层目录),也可以用绝对路径来指定,没有指定classpath时会出现”找不到或无法加载主类…“的错误。也可以在windows的系统环境变量中配置CLASSPATH,这样就可以不用每次都使用-cp参数
  2. 如果给上面的程序加上package关键字时,编译运行又会不同,如下图:
    这里写图片描述
    这里指定了类路径还是找不到主类,解决这个问题之前,先来看一下java解释器的运行过程

    1. 先找出classpath,classpath包含的目录作为查找.class文件的根目录
    2. Java解释器获取包的名称,并将每个句点替换成反斜杠,以从classpath中产生一个路径名称(示例中是package2,只有一层,不用替换)
    3. 将得到的路径与classpath中的各个不同的项连接,得到不同的路径,解释器会在这些目录下寻找与你所要创建的类名称相关的.class文件

    对于使用”java -cp . Main”来运行Main程序时,java解释器会得到一个C:\Users\lzy\Desktop\package2\package2的文件夹,它在当前文件夹(下图中package2)中寻找package2时,发现找不到,所以返回错误。
    这里写图片描述
    所以要正确运行当前程序,要指定classpath为package指定的目录的上一层目录(在这个示例中为Desktop),运行结果如下:
    这里写图片描述

  3. 上面所说的都是单个java文件的情况,当一个.java文件的类中引用另一个.java文件的类时,情况又会复杂很多。

    • 处于同一个文件夹下的所有.java文件,默认属于同一个默认包(即未命名包),所以它们可以直接访问对方的除了private修饰之外的所有成员。

      看下面两个同处于package2文件夹中的程序:

      //当前目录为C:/Users/lzy/Desktop/package2
      
      public class Main{
          public static void main(String args[]){
              Second sec=new Second();
              sec.f();
          }
      }
      //当前目录为C:/Users/lzy/Desktop/package2
      
      public class Second{
          void f(){
              System.out.println("Second.sec()");
          }
      }

      程序运行结果如下,可以看到Main类直接调用了Second类的f()方法:
      这里写图片描述

      如果直接编译,而不指定classpath,会出现找不到符号的错误
      java编译器默认的classpath是当前目录,如果没有指定classpath,编译器会在当前目录中查找java源文件,所以前面的两个例子能够在不指定classpath时编译成功,但是当类中引用了另一个Java文件的类时,它找不到引用的那个类,可能是因为默认的classpath只能用于查找要编译的那个类,不能用于引用的类,如果使用”javac Main.java Second.java”或者”javac *.java”来编译的话能够编译成功(这只是我的猜想,正确与否有待验证)

    • 处于不同文件夹的java源文件,如果没有指定package,它们也都是属于同一个默认包的,也都可以直接互相访问对方除了private之外的成员。

      下面用两个分别属于不同文件夹的java源文件来演示,文件的树结构如下:
      这里写图片描述

      //当前目录为C:/Users/lzy/Desktop/package2
      
      public class Main{
          public static void main(String args[]){
              //在main()类中调用Test类的函数
              Test1 test1=new Test1();  
              test1.f();
          }
      }
      //当前目录为C:/Users/lzy/Desktop/temp/package1
      public class Test1{
          void f(){
              System.out.println("Test1");
          }
      }

      运行结果如下图:
      这里写图片描述
      这里既要指定Test的目录,也要指定当前目录”.”,因为当使用-cp指定目录时,默认的目录会被覆盖。

    • 如果程序中指定了package,则要引用该类就必须使用关键字import来使package中的名称可用,另一个选择是给出包括package在内的完整的名称。

      给上面的Test1类加上”package temp.package1;”,并将f()方法改为public修饰,Main类改为如下代码:

      //当前目录为C:/Users/lzy/Desktop/package2
      public class Main{
          public static void main(String args[]){
          //使用import的话,就可以不用写类前面的那些很长的包名
              temp.package1.Test1 test1=new temp.package1.Test1();
              test1.f();
          }
      }

      程序运行结果如下:
      这里写图片描述
      这里,因为Test1类的package为temp.package1,所以,指定classpath时,只能指定tmep目录的上一层目录即Desktop目录,还有因为Main类和Test1类属于不同的package,所以只能访问Test1类的public修饰的成员。

  4. 如果想要将编译生成的.class文件放到某个特定的目录,可以使用-d 参数

    • 如果程序中没有package,则生成的.class文件会直接放到-d指定的目录下
    • 如果程序指定了package,则编译器会在-d指定的目录下创建package所指定的路径

    还是使用上面的的Main和Test1程序来示例,将.class保存到package2文件夹下面的out文件夹,运行结果如下图
    这里写图片描述
    编译后生成的文件目录树如下:
    这里写图片描述
    可以看到,在out目录下创建了temp/package1文件夹

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值