Java开发教程3-分包与注释

xianaldai 2026-08-11 17:41 1

本期是Java开发教程系列的第三期,本期主要向各位介绍两个"组织代码"的基础知识——分包注释.若你已经熟悉 package/import 和 javadoc,可以跳过本期内容.


每期叠甲:


时间仓促,水平有限,文中难免存在缺点和错误,恳请广大开发者和从业者指正.




一、为什么需要包


第 2 期里,我们的 StudentMain 都直接放在默认包里——只要不写 package 声明,类就属于默认包.练习时没问题,但真实项目会有两个麻烦:




  1. 文件一多就没法找:几十上百个类全堆在一个文件夹里,想找"学生相关的"得来回翻




  2. 类名会撞车:两个功能没法写相同的类名




(package)就是为了解决这两件事:把类按功能分到不同的"文件夹"里;同名的类只要在不同包里,就不冲突.




二、声明包:package


.java 文件的第一行写:



package com.mycodes.demo;

public class Student {

// ...

}




  • package 声明这个类属于哪个包,必须写在文件第一行,前面不能有其他代码(注释除外)




  • 包名对应磁盘上的目录结构:包 com.mycodes.demo 对应目录 com/mycodes/demo/,类文件就放在这个目录里




  • 包名规范:全小写,一般用反域名.比如你的网站是 mycodes.com,包名就用 com.mycodes.xxx.域名全球唯一,反着写就能避免全世界的类撞包名




  • 不写 package 就是默认包.默认包不能被 import,只适合练习用,正式项目不要用






三、导入:import


不同包里的类,要先 import 进来才能直接用:



import com.mycodes.demo.Student;

public class Main {

public static void main(String[] args) {

Student s = new Student(); // 现在可以直接用 Student

}

}



  • 想一次性引入一个包里的一堆类,可以偷懒用通配符 `*`:



import java.util.\*; // 引入 java.util 包里的所有类


* 有局限,别依赖它:




  1. 只管这一个包,不含子包:import java.util.* 只导入 java.util 包里直接定义的类,java.util.regex 这类子包里的类还是要单独 import——想用里面的 Pattern,得再写一行 import java.util.regex.Pattern; , * 帮不了你




  2. 撞名时照样救不了:如果两个包都用 * 导入了,而它们各有一个同名类(比如 java.util.*java.awt.* 里都有 List),直接写 List 照样编译报错——这时只能写全限定名,或者去掉一个 *、改成显式导入其中某个类




  3. 看不清依赖:* 让读者看不出这个文件到底用了哪些类,代码量一大可读性就下降,很多工程规范直接禁止用 *




所以结论:单个类就写单个 import;同一包要用的类确实很多时才考虑 `*`,并且时刻记得它只管当前这一层.




  • 同一个包里的类不需要 import,直接写类名就行




  • java.lang 包(里面有 StringSystem 等最常用的类)默认自动导入——所以前几期我们直接用 StringSystem.out,从没写过 import




  • 想不 import,也可以写全限定名(包名加类名,如 com.mycodes.demo.Student),但那样太啰嗦(这个其实在IDE可以快捷import,因此我们推荐写import)






四、public 和默认访问


跨包用别人的类,得知道一个前提:类里的东西默认只能被同一个包访问,被 public 修饰的东西才允许任何地方访问.



package com.mycodes.demo;

public class Student {

public String name; // public:谁都能访问

String secret; // 默认:只有同包能访问

public void sayHello() {

System.out.println("你好,我是 " + name);

}

}




  • 类前面写了 publicpublic class Student),别处的类才能 new 它




  • 方法前面写了 public,别处的类才能调用它




  • 什么都没写的字段/方法,只有同一个包里能用;跨包访问会编译报错




本期只需要记住这一个规则就够用,完整的四种访问级别(public/protected/ package-private/private)下一期专门讲.




五、注释与 javadoc


注释是写给看的,编译器会直接忽略.有三种:


5.1 行注释 // xxxxx 和块注释 /* */



// 这是单行注释,直到这一行结束

/*

* 这是块注释,可以跨多行.

* 一般用来给一段代码做说明.

*/


5.2 javadoc 注释 /** */



/**

* 这是 javadoc 注释.

* 写在类或方法前面,描述它"是什么、怎么用".

*/

public class Student {

// ...

}


javadoc 比普通注释多两件事:




  • 可以在里面写 @param(参数说明)和 @return(返回值说明)




  • IDE 会在你鼠标悬停到类名或方法名上时,把 javadoc 显示成小提示——自己写过的代码,几个月后翻回来,悬停一下就能想起它是干嘛的(下图就是)




给方法写 javadoc 的例子:



/**

* 判断学生是否及格.

*

* @param threshold 及格线,低于它算不及格

* @return 成绩大于等于及格线返回 true,否则返回 false

*/

boolean passed(double threshold) {

return score >= threshold;

}


写注释的三个建议:




  • 写"为什么这么做",而不是"做了什么"——i++ 谁都看得懂,但"为什么这里要加一"才值得写




  • 公开的类和方法,养成写 javadoc 的习惯




  • 注释不要太多太碎,否则和代码一样难读






六、小项目:带包名的学生类


把本期内容串起来,建一个真正带包的小项目.目录结构:



codes/

└── src/

├── com/mycodes/demo/ ← 包 com.mycodes.demo

│ └── Student.java

└── com/mycodes/app/ ← 包 com.mycodes.app

└── Main.java


文件一 com/mycodes/demo/Student.java:



package com.mycodes.demo;

public class Student {

public String name;

public double score;

/**

* 创建一个学生.

*

* @param name 学生姓名

* @param score 学生成绩

*/

public Student(String name, double score) {

this.name = name;

this.score = score;

}

/**

* 判断是否及格.

*

* @return 成绩大于等于 60 返回 true,否则返回 false

*/

public boolean passed() {

return score >= 60;

}

}


文件二 com/mycodes/app/Main.java:



package com.mycodes.app;

import com.mycodes.demo.Student;

public class Main {

public static void main(String\[\] args) {

Student s1 = new Student("小明", 92);

Student s2 = new Student("小红", 58);

System.out.println(s1.name + ":" + (s1.passed() ? "及格" : "不及格"));

System.out.println(s2.name + ":" + (s2.passed() ? "及格" : "不及格"));

}

}


运行结果:



小明:及格

小红:不及格


注意几个点:




  • Maincom.mycodes.app,Studentcom.mycodes.demo,靠第一行的 import com.mycodes.demo.Student; 引入




  • 两个类都标了 public,所以能跨包使用




  • 每个类和方法前都写了 javadoc,鼠标悬停 new Student(...) 时,IDE 会显示"创建一个学生"的说明





小知识:IDE(如 IntelliJ IDEA / Eclipse)建包时,会在磁盘上自动生成对应的目录;编译后类的"完整名字"是"包名 + 类名".





朝花夕拾:终于看懂第 1 期的 import 了


第 1 期我们用 ArrayListHashMap 时,开头写过:



import java.util.ArrayList;

import java.util.List;

import java.util.HashMap;

import java.util.Map;


当时没说为什么.现在你知道了:ArrayListHashMap 这些类并不在 java.lang 里,而在 java.util 包里,所以要先用 import 把它们引进来才能直接用.java.util 就是 JDK 自带的"工具类"包——ScannerRandomCollections 等等都在里面,后面会经常见到.




总结


本期学习了两个"组织代码"的基础知识:




  • 分包:package 声明类所属的包,包名对应目录结构,用反域名规范避免撞名;不同包的类用 import 引入




  • public 与默认访问:public 允许任何地方访问,什么都不写只允许同包访问(完整规则下一期讲)




  • 注释:行注释 //、块注释 /* */、javadoc /** */;用 @param/@return 写参数和返回值的说明




下一期我们学习访问控制与封装——把四种访问级别讲完整,并学会用 private + getter/setter 把数据保护起来.

最新回复 (2)
  • xianaldai 楼主 08-11 18:04
    1

    把markdown编辑器换成新编辑器被命中了

  • Neo 08-11 22:18
    2

    点赞,看到这系列帖子,一下给我拉回了好多年前的感觉。

* 帖子来源Linux.do
返回