
目录一、类Java世界的唯一居民二、main方法程序的唯一入口三、包命名空间的分层管理四、import跨包的类引用五、命名规范约定优于配置六、结语一、类Java世界的唯一居民任何Java程序都由类构成。这不是一种可选的编程风格而是Java语言规范中的强制性约束——所有可执行代码必须封装在类内部。这一规则在面向对象语言中并不罕见但Java将其贯彻得比大多数语言更彻底。初学者可能会问为什么不能像Python或JavaScript那样直接在文件里写一行print(Hello)就执行答案在于Java的设计哲学。Java从一开始就定位为一门面向对象的工程语言其创建者认为即使是简单的程序也应该服从面向对象的基本框架。将代码封装在类中不是束缚而是强制开发者从第一天起就以结构化的方式思考程序。从JVM的角度看类首先是代码的组织单元其次才是对象的蓝图。JVM只认识类——编译后的字节码以类为单位组织类加载器以类为粒度加载方法区以类为容器存储静态变量和方法字节码。一个没有类的Java程序在物理上就不存在——javac编译器会拒绝编译任何不在类内部的方法或语句。一个最基本的类声明包含三个要素。访问权限修饰符——public表示这个类对任何其他类可见class关键字——告诉编译器接下来是一个类的定义类名——必须与文件名完全一致。这些要素共同构成了Java程序的基本骨架。二、main方法程序的唯一入口main方法是Java程序的入口点。JVM启动一个Java程序时会找到指定类中符合精确签名的main方法从它的第一行代码开始执行到它的最后一行代码执行完毕时程序结束。main方法的方法签名是固定的public static void main(String[] args)。这行声明中的每一个关键字都有其不可替代的作用理解它们不仅是记忆语法更是理解JVM调用机制的切入点。public确保JVM能够从类外部访问这个方法。JVM本身也是一个程序它在启动时需要从外部调用你写的main方法。如果main方法的访问权限不是publicJVM在尝试调用时会被Java访问控制机制拒绝程序无法启动。static让JVM无需创建对象就能直接调用main方法。这是main方法必须为static的核心原因JVM启动时内存中还没有任何你的类的实例存在。如果main方法是普通实例方法JVM必须先创建一个对象才能调用它——这就陷入了“先有鸡还是先有蛋”的困境。static方法属于类本身而非类的实例在类加载到JVM后即可被调用无需等待对象创建。void声明main方法不返回任何值。JVM不会从main方法获取返回值——程序的状态通过退出码传递给操作系统。如果需要向操作系统传递程序执行结果应使用System.exit(状态码)而非依赖main方法的返回值。String[] args是命令行参数数组。它允许用户在启动程序时从命令行向程序传递信息。如果你在命令行执行java HelloWorld arg1 arg2 arg3args数组将包含三个元素arg1、arg2、arg3。这一机制让同一个Java程序可以根据不同的启动参数执行不同的逻辑是很多命令行工具和后台服务的基础。三、包命名空间的分层管理当项目中的类从几个增长到几十个、上百个时将所有类堆在同一个目录下无异于把所有文件扔在桌面上——能工作但很快就会失控。包机制正是为了解决这一组织性问题而设计的。包在逻辑上是类的命名空间。两个同名的类如果位于不同的包中互不冲突。在大型项目中来自不同模块、不同第三方库的类名冲突是常见问题。包提供了名字的隔离——com.example.User和com.other.User虽然是同一个类名但在Java看来是完全不同的两个类。包在物理上是磁盘上的目录层次。声明为package com.example.hello;的类其源文件必须存放在com/example/hello/路径下。javac编译器会检查包声明与文件路径是否一致不一致则报错。这种“逻辑声明与物理路径严格对应”的规则让Java项目的源码组织拥有了天然的可导航性——看到一个类的包名就能立即知道它在项目目录树中的位置。包命名遵循反向域名的约定。如果你的公司域名为example.com所有包名以com.example开头。这种命名策略利用了域名系统的全球唯一性来避免包名冲突——两个不同组织不太可能拥有相同的域名因此不会产生相同的包前缀。四、import跨包的类引用包将类隔离到不同的命名空间中但程序需要跨包引用类。import语句正是为此而设计。有两种方式可以引用外部类。一是使用类的完全限定名——在代码中写出包含完整包路径的类名。每次引用都要写全路径代码冗长且难以阅读。二是使用import语句——在文件开头声明要导入的类之后在代码中可以直接使用简单类名。import语句只是告诉编译器“当我写SimpleName时实际指的是com.example.FullName”在编译后的字节码中所有类名仍然会展开为完全限定名——import只是编译期的语法糖。需要注意import com.example.*只会导入com.example包下的类不会导入其子包中的类。Java的包在命名上虽然是层次化的但在语义上并不存在真正的“父子”关系。com.example和com.example.util是两个完全独立的包编译器不会因为星号导入而递归扫描子包。java.lang包是唯一的例外——这个包中的核心类String、System、Math等被Java语言规范要求隐式导入不需要在任何文件中显式import即可直接使用。这一设计体现了Java语言设计者对“哪些功能是语言基础设施”的判断。五、命名规范约定优于配置Java社区经过数十年的实践形成了一套约定俗成的命名规范。这些规范不是编译器的强制要求但遵守它们是职业素养的基本体现也是团队协作的高效前提。类名使用大驼峰命名——每个单词首字母大写。类名应当是名词或名词短语因为类是对现实世界“事物”的抽象。方法名使用小驼峰命名——首字母小写后续单词首字母大写。方法名应当是动词或动词短语因为方法描述的是“行为”。常量名全大写单词之间用下划线分隔。常量是使用static final修饰的不可变变量。包名全小写使用点分隔遵循反向域名规则。这些规范看似琐碎但它们共同构成了Java代码的“面孔”。任何有经验的Java程序员拿到一份陌生代码首先就是通过这些命名规范来判断代码的作者是否专业。规范不是束缚而是团队沟通的无声语言。六、结语类、main方法和包共同构成了Java程序的骨架。类提供了代码的组织容器main方法提供了程序的启动入口包提供了命名空间的分层管理。这三者不是各自独立的知识点而是相互协同的语言基础设施——包将类组织为层次化的命名空间类的main方法让JVM能够启动程序import让类之间能够相互引用。下一篇我们将进入Java程序的“血肉”层——基本数据类型与变量。整数、浮点数、字符与布尔值在JVM中如何存储基本类型与引用类型为何被设计为两套体系以及自动装箱与拆箱在字节码层面到底做了什么。