JAVA-包和import

目录

1、java包机制

2、域名倒序

3、加入包机制后的编译和运行

4、包名的省略

4、import关键字

5、import导入分类


1、java包机制

        作用:划分代码功能,方便程序的管理,对类进行一定的划分,易于管理和维护

        语法:定义再程序的最前排,在程序的首行编写,并且只能有一句,因为类只会存在于一个包中

package  包名;

        包名要全部小写,是标识符,要遵守标识符的命名规则。

回顾——标识符的命名规则

我们可以且有权利对其进行命名的都是标识符

  • 可以是字母、数字、下划线 、$组成,不能含有其他的符号,包括空格也不可以,因为空格也是特殊字符。
  • 不能以数字开头
  • 严格区分大小写
  • 关键字不能做标识符
  • 理论上无长度限制,但是不要太长

标识符的命名规范【行内默认的规定】

  • 起名要见名知意
  • 驼峰命名法
  • 类名、接口名:首字母大写,其后单词首字母大写
  • 变量名、方法名:首字母小写,后面每个单词首字母大写
  • 常量名:全部大写,如果有多个单词组成,单词和单词之间用下划线隔开

        包名命名方式:公司域名倒序+项目名+模块名+功能名;

               采用这种命名方式能够降低重名率,更加的直观,易于代码的组织管理。

        结构:一个包对应一个目录,目录的各层级之间使用 “ · ”隔开。

2、域名倒序

       例如,对于百度的网址 www.baidu.com,它的域名:baidu.com,那么域名的倒序就是com.baidu;

3、加入包机制后的编译和运行

       注意加入了包机制之后,就相当于包名是姓氏,类名是名字,只有包名+类名才能够正确的表示当前类,所以真正的类名是全类名=包名+类名。

        那么在编译和运行的时候【指令 +类名】中的类名应该是全类名。

        例如代码如下所示:在包test中有一个类test05

package test;
public class test05 {
    public static void main(String[] args) {
        System.out.println("Die");
    }
}

        通过命令javac进行编译,然后如下运行,发现有报错,查询当前test05.java文件的路径为【D:\Idea\JAVATEST\src\test】,很明显,当前运行的路径没有错误,为什么无法运行呢?看test05类的代码,发现是有package语句的,所以这个类真正的名字是:包名 · 类名=test.test05。

D:\Idea\JAVATEST\src\test>javac test05.java

D:\Idea\JAVATEST\src\test>java test05
错误: 找不到或无法加载主类 test05

        那么尝试对类名进行修改,运行后如下:很明显完成了输出操作。

D:\Idea\JAVATEST\src>java test.test05
Die

        有命令:【javac -d 编译之后的路径  java源文件的路径】指将java源文件进行编译后生成的字节码文件放到“编译之后的路径”中

        如上代码,执行如下:

D:\Idea\JAVATEST\src>javac -d D:\Idea\JAVATEST\src D:\Idea\JAVATEST\src\test05.java

        test05.java的路径:D:\Idea\JAVATEST\src\test05.java

        在编译之后,test05.class的路径就在D:\Idea\JAVATEST\src\test\test05.class

        类加载的时候默认从当前路径下加载,所以先将路径切换到文件所在的路径,然后再运行,运行的时候,名字用全类名。

        例如用idea进行代码的编写,如下:会报错

         因为test05.java和test06.java不在同一个包中,所以在test05的文件中是找不到test06.java文件的,因为两个类的姓氏不一样。

        所以应该用类的全称去进行实例化,如下所示:

package test01;

public class test06 {
    public void sys(){
        System.out.println("Die");
    }
}
public class test05 {
    public static void main(String[] args) {
       test01.test06 test=new test01.test06();   //用全类名去实例化一个对象
        test.sys();
    }
}

        输出结果:是可以实现正常输出的

Die

Process finished with exit code 0

4、包名的省略

        如果两个类在同一个目录(包)下,就可以省略包名。例如同包下的两个java类(test06-test07):

        test06.java:

package test01;

public class test06 {
    public static void main(String[] args) {
        test07 test07=new test07();
        System.out.println(test07.i);
    }
}

        test07.java

package test01;

public class test07 {
    int i=0;
}

        运行结果:正常输出,没有错误或者异常

0

Process finished with exit code 0

        否则不能省略,因为省略了包名之后,在寻找这个类的文件的时候,会在当前包中寻找,如果找不到会导致报错,如上文的示例(test05-test06)。

        那么如果不在同一个包中,想要省略包名怎么办呢?import的关键字就出现了。

4、import关键字

       那么问题就出现了,如果在我们进行代码编写的时候,利用全类名去进行代码的编写,十分的浪费时间,而且增加代码理解和阅读的复杂度。这种时候,我们就想要省略包名,简化代码的编写,那么导包的功能的出现就成为了必然。

         关键字:import

         语法:import  包名.类名或者通配符

         作用:一次性导入其他包中的我们所需的类,这样在这个类中就可以使用导入的包中的类,不必用包名做前缀,省略包名,直接通过类名去创建对象,更加的快捷方便。

        原理:import 只是请编译器帮你打字,让编译器把没有姓的类别加上姓,并不会把别的档案的代码写入进来。

         注意:导包语句编写在包语句之下,class定义之上

         特殊包:

         其他包:需要手动的通过import关键字进行导入。

        如下几行代码:

     java.io.InputStream is = java.lang.System.in;
     java.io.InputStreamReader isr= new java.io.InputStreamReader(is);
     java.io.BufferedReader br = new java.io.BufferedReader(isr);

        代码十分的繁琐,通过import语句导入上述代码中的包名们

     import java.lang.System;
     import java.io.InputStream;
     import java.io.InputStreamReader;
     import java.io.BufferedReader;

        代码就可以简化为如下,很明显代码已经简洁了很多。

     InputStream = System.in;
     InputStreamReader isr = new InputStreamReader(is);
     BufferedReader br = new BufferedReader(isr);

 5、import导入分类

        ①单类型导入(single-type-import) 

        ②按需类型导入(type-import-on-demand) 

        从名字就可以看出来,导入的是类型,不是源代码,它只是拜托编译器帮忙补充没有姓氏的那些类名。

        导入的类或接口的简名(simple name)具有编译单元作用域.这表示该类型简名可以在导入语句所在的编译单元的任何地方使用.这并不意味着你可以使用该类型所有成员的简名,而只能使用类型自身的简名。例如: java.lang包中的public类都是自动导入的,包括Math和System类.但是,你不能使用简名PI()和gc(),而必须使用Math.PI()和System.gc().你不需要键入的是java.lang.Math.PI()和java.lang.System.gc().

       编译器会自动导入 java.lang包,所以无需程序员手动的进行包的导入,如果重复导入了包怎么办呢?编译器会清楚冗余的导包声明。

        注意按需类型导入的方式要适度应用,虽然不会影响代码的执行速度,但是它会影响代码的编译速度。

参考内容:

        因为单类型导入和按需类型导入对类文件的定位算法是不一样的。
  java编译器会从启动目录(bootstrap),扩展目录(extension)和用户类路径下去定位需要导入的类,而这些目录仅仅是给出了类的顶层目录【即包的上一级目录】。编译器的类文件定位方法大致可以理解为如下公式:
  顶层路径名 \ 包名 \ 文件名.class = 绝对路径
  对于单类型导入很简单,因为包明和文件名都已经确定,所以可以一次性查找定位。
  但是对于按需类型导入则比较复杂,编译器会把包名和文件名进行排列组合,然后对所有的可能性进行类文件查找定位。例如代码的开头如下:
  package com;
  import java.io.*;
  import java.util.*;
  当你的类文件中用到了File类,那么可能出现File类的地方如下:
  1、File \ File类属于无名包,就是说File类没有package语句,编译器会首先搜索无名包
  2、com.File \ File类属于当前包
  3、java.lang.File \编译器会自动导入java.lang包
  4、java.io.File
  5、java.util.File
  需要注意的地方就是,编译器找到File类之后并不会停止下一步的寻找,而要把所有的可能性都查找完以确定是否有类导入冲突。

        假设此时的顶层路径有三个,那么编译器就会进行3*5=15次查找。

        【对于如上的导入方式,可以发现有五种包名和文件名组合的方式,因为完整的路径是加上顶层的目录,即包的上一级目录,构成的一个绝对地址,所以以上五种情况,加上不同的顶层目录前缀,共有15种可能性】


  了解以上原理之后,我们可以得出这样的结论:

        按需类型导入是绝对不会降低Java代码的执行效率的,但会影响到Java代码的编译速度,因为需要进行完整的匹配和筛选对比。

        按需类型导入的缺点:

        1)编译速度:在一个很大的项目中,它们会极大的影响编译速度.但在小型项目中使用在编译时间上可以忽略不计。
        2)命名冲突:解决避免命名冲突问题的答案就是使用全名.而按需导入恰恰就是使用导入声明初衷的否定. (例如:当你import java.awt.;import java.util.后,使用List的时候编译器将会出编译错误),在idea中会存在自动优化,不需要得包也会优化掉。
        3)说明问题:全名的使用更加的直白.毕竟高级语言的代码是给人看的,按需导入可能会导致代码的理解问题。
        4)无名包问题:如果在编译单元的顶部没有包声明,Java编译器首选会从无名包中搜索一个类型,然后才是按需类型声明.如果有命名冲突就会产生问题。(例如:顶层目录为D:\test,这个路径下有一个test05.java文件和包A,我们想要的java文件所在的路径为:D:\test\A\B\test05.java,其全类名为:A.B.test05.java,在搜索的时候,会在两个路径都发现这个java文件,虽然在顶层路径中找到了,但是还是会扫描所有的可能路径,这样有可能会产生命名冲突问题,合理利用开发工具能够很大程度上避免一些错误或者及时发现错误,代码编写更加的高效,代码也会更加的优化)。

常用的包
        Java.lang包:java的核心类库,包含了运行java程序必不可少的系统类,如基本数据类型、基本数学函数、字符串处理、线程、异常处理类等,系统缺省(默认)加载这个包。
        java.util包:Java的实用工具类库。在这个包中,Java提供了一些实用的方法和数据结构。例如,Java提供日期(Data)类、日历(Calendar)类来产生和获取日期及时间,提供随机数(Random)类产生各种类型的随机数,还提供了堆栈(Stack)、向量(Vector) 、位集合(Bitset)以及哈希表(Hashtable)等类来表示相应的数据结构。
        java.io包:java语言的标准输入/输出类库,如基本输入/输出流、文件输入/输出、过滤输入/输出流等。
        java.util.zip包:实现文件压缩功能。
        java.lang.reflect包:提供用于反射对象的工具。
        java.mah:如提供用于执行任意精度整数算法 (BigInteger) 和任意精度小数算法 (BigDecimal) 的类。
        java.net包:用来实现网络功能的类库。如Socket类、ServerSocket类。
        java.awt包:构建图形用户界面(GUI)的类库。提供的类如:低级绘图操作Graphics类,图形界面组件和布局管理如 Checkbox类、Container类、LayoutManager接口等,以及用户界面交互控制和事件响应,如Event类。
        java.awt.event包:GUI事件处理包。
        java.awt.image包:处理和操纵来自于网上的图片的java工具类库。
        java.sql包:实现JDBC的类库。
        java.applet包:编写java applet程序用的。

        在大型工程中,一般的书写建议是:采用单类型引入,而且即使是同一个package下的,也要import,避免歧义得发生。



参考链接:

http://t.csdn.cn/8mHE0http://t.csdn.cn/8mHE0https://blog.csdn.net/qq_37958652/article/details/89222042http://xn--uir93xlrs/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值