美文网首页
java 类(包)导入及使用

java 类(包)导入及使用

作者: mysimplebook | 来源:发表于2020-01-17 16:15 被阅读0次

为了在编译阶段能够找到类中出现的(不在本类中声明)符号标记(变量、函数、类、方法),我们需要在 Java 程序中明确它们在具体哪个类,而使用一个类需要给出完整的类名,否则报cannot find symbol错误。如果在程序中每次都指定完整的类名是非常繁琐的,而使用 "import" 语句可解决此问题。

导入语法

导入包的语法格式为

                                import pkg1[.pkg2…].(classname|*);

其中,*表示导入包下面的所有类或包路径下所有类文件。源文件中可以包含任意数量的 import 声明。import 声明必须在包声明之后,类声明之前。如果没有package语句,那么import语句应该在源文件中最前面。

如新建一个Shoe.java文件

[root@localhost test]# cat Shoe.java

package com.XXX.shoe;

public class Shoe{

        private static String color;

        private static String size;

        public Shoe(String color,String size){

                this.color=color;

                this.size=size;

        }

        public void getshoe(){

                System.out.println("i'm making a pair of shoes with color "+this.color +" and size "+this.size);

        }

}

主类源文件

[root@localhost test]# cat Clothes.java

import com.XXX.shoe.Shoe;

public class Clothes{

        public static void main(String [] args){

                Clothes c1=new Clothes("red","XL");

                c1.getcloth();

                Shoe s1=new Shoe ("red","41");

                s1.getshoe();

        }

}

那么怎么运行这个主文件呢?

我们可以分开编译这两个文件的源码.java。这样,你可以将你的类目录(.class文件)分享给其他的编程人员,而不用透露自己的源码。用这种方法管理源码和类文件可以让编译器和java 虚拟机(JVM)可以找到你程序中使用的所有类型。

我们先编译Shoes.java文件,这是必须的,因为Clothes.java中依赖这个文件

[root@localhost test]# javac -d . Shoes.java   

再编译、运行Clothes.java文件

[root@localhost test]# javac Clothes.java

[root@localhost test]# java Clothes

i'm making a XL size cloth with color red

i'm making a pair of shoes with color red and size 41

[root@localhost test]#

因此在Java中,import语句给出一个完整的限定名,包括包名、类名,那么Java编译器和JVM就可以很容易地定位到源代码或者类文件。

另外一种方法是两个源文件在同一个命令中编译,如

[root@localhost test]# javac -d . Shoe.java Clothes.java

还有一种方式是将被导入源文件放入包名对应的路径下,直接编译主源文件,如我们先把Shoe.java文件放入包名对应的路径./com/XXX/shoe/下,保证该路径无Shoe.class文件。直接编译、运行主类源文件

[root@localhost test]# javac Clothes.java

[root@localhost test]# ll com/XXX/shoe/

total 8

-rw-r--r-- 1 root root 771 Jul 24 18:26 Shoes.class                    #类文件

-rw-r--r-- 1 root root 403 Jul 24 18:22 Shoes.java

[root@localhost test]#

[root@localhost test]# java Clothes                              #Clothes.class 在当前目录

i'm making a XL size cloth with color red

i'm making a pair of shoes with color red and size 41

[root@localhost test]#

可见,主类中在编译的时候,如果遇到导入外部包(类)的时候,会去编译包路径下的源码文件,这样外部类的源码与编译后的类文件路径一样。

import packagename.classname的使用

使用import导入的类,有多种形式,使用它们时需要注意。具体规则如下

• 同一个包中的可以直接访问

• 无包的类可以访问有包的类,直接导入即可

• 有包的类无法访问无包的类

• 由于使用不同包中的类需要导入,而无包的类因无包名无法导入

导入同一个包中的类

如果导入类和使用类位于同一个包里,则可以直接使用,无效显式导入。如一个测试主类

[root@localhost test]# cat Test.java

package com.XXX.shoe;

public class Test{ 

        public static void main(String[] args) {

                Shoe s1=new Shoe ("red","41");

                s1.getshoe();

        }

}

测试

[root@localhost test]# javac -d . Test.java

[root@localhost test]# java com.XXX.shoe.Test

i'm making a pair of shoes with color red and size 41

导入默认包中的类

假如一个类不加package名就属于默认包,没有包声明,编译器创建一个默认包空间。使用这些类的时候,import语法是无效的。强制使用会编译失败。

从 J2SE 1.4 开始,Java 编译器不再支持 import 未命包名的类、接口。  J2SE 1.4 与 J2SE 1.3 兼容性文档中(http://java.sun.com/javase/compatibility_j2se1.4.html)说明了这一事实:The compiler now rejects import statements that import a type from the unnamed namespace. Previous versions of the compiler would accept such import declarations, even though they were arguably not allowed by the language (because the type name appearing in the import clause is not in scope). The specification is being clarified to state clearly that you cannot have a simple name in an import statement, nor can you import from the unnamed namespace.

那么如何调用默认包里的类呢?这里要用到反射机制。

不同包的类互相调用

如果类位于不同的包中,那么就需要指定导入类的详细路径,如

[root@localhost test]# vi Test.java

package com.XXX.test;

import com.XXX.shoe.Shoe;              //显式导入

public class Test{

        public static void main(String[] args) {

                Shoe s1=new Shoe ("red","41");

                s1.getshoe();

        }

}

测试

[root@localhost test]# javac -d . Test.java

[root@localhost test]# java com.XXX.test.Test

i'm making a pair of shoes with color red and size 41

若没有import语句,编译报错

Test.java:9: error: cannot find symbol

                Shoe s1=new Shoe ("red","41");

                ^

  symbol:  class Shoe

  location: class Test

默认包中的类使用非默认包中的类

如前所述,这是完全可以的。

但是注意如果使用import packagename.*这种格式时,被导入包的源码.java文件不要和使用该包的主程序.java文件放入同一个目录下面,否则编译报错,如

[root@localhost test]# vi Test.java

//package com.XXX.test;

import com.XXX.shoe.*;

public class Test{

        public static void main(String[] args) {

                Shoe s1=new Shoe ("red","41");

                s1.getshoe();

        }

}

其中,Test.java和Shoe.java位于同一个目录下面。

编译主程序

[root@localhost test]# javac Test.java

Test.java:9: error: cannot access Shoe

                Shoe s1=new Shoe ("red","41");

                ^

  bad source file: ./Shoe.java

    file does not contain class Shoe

    Please remove or make sure it appears in the correct subdirectory of the sourcepath.

1 error

这是为什么呢?

这是因为java中包声明就是声明一个命名空间,当导入包时,也就是去导入命名空间。在编译Test.java时,因为没有包声明,编译器创建一个默认包空间,优先在本级目录下寻找包名中的同名文件,而不是包目录,但是编译器找到的是同名的.java文件而不是.class文件,所以报错。

解决方法有两种,

删除Shoe.java文件或移动到其他目录下,这么做以后,编译器就知道需要到com/XXX/shoe路径下去寻找类文件了。

另外一种方法是,将import com.XXX.shoe.*替换为 import com.XXX.shoe.Shoe。这就是告诉编译器去com/XXX/shoe找Shoe类文件。如果非要用import com.XXX.shoe .*,你需要在代码中显式使用com.XXX.shoe.Shoe。如

com.XXX.shoe.Shoe s1=new com.XXX.shoe.Shoe ("red","41");

相关文章

  • java 类(包)导入及使用

    为了在编译阶段能够找到类中出现的(不在本类中声明)符号标记(变量、函数、类、方法),我们需要在 Java 程序中明...

  • Objective-C 基础

    package oc 中没有包(package)的概念, Java import oc 导入命令,导入系统类库使用...

  • java基础知识(二)

    一、使用Arrays类操作java中的数组 使用前先导入包 import java.util.Arrays; 1....

  • Java Scanner input

    使用Scanner工具类来获取用户输入的成绩信息 Scanner类位于java.util包中,使用时需要导入此包 ...

  • 三 常用API第二部分——第四节 System 类

    java.lang 包中。无需导入。 静态方法,可以通过类名直接使用

  • Java常用类库-Date类

    Date 类 在 java.util 包中,因此在使用 Date 类时需要导入该包。Date 类 表示特定的时间瞬...

  • JDK 学习笔记 之Object类中方法

    1. 为什么使用 java.lang 包下的所有类,都不需要手动导入 因为编译器会默认导入java.lang 包,...

  • scala:import

    java中的import叫导入类,scala叫导入包 默认自动引入的包java.lang.*、scala.*、Pr...

  • Scanner工具类

    1.使用Scanner工具类来获得用户输入的成绩信息,Scanner类位于java.util中,使用时需要导入此包...

  • Android----识别图片二维码

    导入包 使用代码 工具类

网友评论

      本文标题:java 类(包)导入及使用

      本文链接:https://www.haomeiwen.com/subject/wbaczctx.html