从 TypeScript 到 Java(1):理解类与包结构

从 TypeScript 到 Java(1):理解类与包结构

系列导读: 本系列面向有 TypeScript 基础的开发者,帮助你快速掌握 Java 的核心概念与语言特性。 第一篇,我们从最基础也是最重要的部分开始------类与包结构(Class & Package)

Java 是一个"万物皆类"的世界,所有代码都必须定义在类中,并且类必须归属于某个包(package),而TypeScript 则更灵活,模块与文件关系松散。

💡 为什么要从类与包开始学?

在 TypeScript 中,我们习惯了灵活的模块系统: 一个文件可以导出函数、对象、类,也可以随意组合模块结构。

但在 Java 世界里,一切都更"严格"和"有序":

  • 所有代码都必须定义在 类(class) 中;
  • 每个文件只能包含 一个 public 类
  • 类所在的包(package)必须与 文件夹路径完全对应
  • 类名、文件名、包名,都遵循固定规则。

这种看似"繁琐"的规则,实际上是 Java 构建大规模工程可维护性的基础。

🧱 Java 中的类结构

让我们从最简单的 Java 类开始:

java 复制代码
// 文件路径:src/main/java/com/example/demo/HelloWorld.java
package com.example.demo;  // 包声明必须在文件首行

public class HelloWorld {
    public static void main(String[] args) {
        System.out.println("Hello, Java!");
    }
}

逐行解释:

  1. package com.example.demo; 声明该类属于 com.example.demo 包,对应的文件夹路径为 com/example/demo/
  2. public class HelloWorld 类名必须与文件名一致。
  3. public static void main(String[] args) 这是 Java 应用程序的入口方法。

在 TypeScript 中,你可能写:

typescript 复制代码
export function hello() {
  console.log("Hello, TypeScript!");
}

两者看似相似,但 TypeScript 文件本身就是一个模块; 而 Java 中,模块(package)是通过目录 + 声明共同定义的。

🗂️ 包(Package)与目录结构

Java 通过包组织代码,类似于命名空间。 一个典型的包名使用 反转的域名

lua 复制代码
com.example.project
org.apache.commons
io.github.username.library

结构示意:

css 复制代码
src/
 └── main/
      └── java/
           └── com/
                └── example/
                     ├── model/
                     │    └── User.java
                     ├── service/
                     │    └── UserService.java
                     └── App.java

每个子文件夹对应一个包。 当你在 UserService.java 中引用 User 时,需要显式导入:

java 复制代码
import com.example.model.User;

对比 TypeScript:

typescript 复制代码
import { User } from "./model/User";

区别在于:

  • TypeScript 的模块是文件级的;
  • Java 的包是目录级的;
  • Java 编译器依赖包名确定类路径,因此目录结构必须严格匹配。

⚙️ 默认包与访问规则

如果一个类没有显式写 package,它会自动归入 默认包(default package)

java 复制代码
public class Demo {}

但这样做 不推荐,因为:

  • 默认包下的类无法被有包声明的类导入;
  • 在大型项目中容易冲突;
  • 几乎所有生产项目都会使用命名包。

最佳实践: 始终为你的项目定义根包名,例如:

复制代码
com.yourcompany.project

这能保证项目结构清晰、命名不冲突。

📦 导入与可见性

在 TypeScript 中你使用 import/export; 在 Java 中,通过 import 指令引用其他包的类:

java 复制代码
import com.example.utils.Logger;

public class App {
    public static void main(String[] args) {
        Logger.log("Start app");
    }
}

Java 的导入有三种形式:

  1. 导入单个类:import com.example.User;
  2. 导入整个包:import com.example.*;
  3. 导入静态成员(Java 5+):import static com.example.Utils.PI;

建议只导入需要的类,避免 * 导入污染命名空间。

🚀 实战建议:动手写一个多包小项目

可以尝试创建如下项目结构:

复制代码
com.example.app
 ├── model/
 │    └── Product.java
 ├── service/
 │    └── ProductService.java
 └── App.java
  • Product.java 中定义一个简单类;
  • ProductService.java 中使用它;
  • App.javamain 方法中调用服务;
  • 编译运行,观察包结构如何影响导入。

通过亲手写一遍,你会立刻体会到 Java 的包系统是如何组织大规模项目的。

🧭 TypeScript 思维迁移图

TypeScript 概念 Java 对应概念 关键区别
模块(module) 包(package) Java 强制目录与包一致
export class public class Java 一个文件一个 public 类
import {...} from import com.xxx Java 编译依赖包路径
任意文件执行 main 方法入口 Java 程序需从 main 启动

✅ 小结

从 TypeScript 过渡到 Java,理解 类与包结构 是第一步。 Java 的严格结构看似限制自由,但正是这种约束,保证了项目的可维护性和可扩展性。

记住两句话:

  • Java 中"一切皆类";
  • 包名与目录结构必须完全对应。

当你能熟练地创建多层包结构、理解类之间的组织关系时, 你已经迈入 Java 世界的第一扇大门。

👉 下一篇预告

《从脚本执行到 main 方法:理解 Java 的程序入口》 我们将深入讲解 main 方法的执行逻辑、参数机制和运行时结构。

相关推荐
想用offer打牌6 小时前
MCP (Model Context Protocol) 技术理解 - 第二篇
后端·aigc·mcp
崔庆才丨静觅6 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60617 小时前
完成前端时间处理的另一块版图
前端·github·web components
KYGALYX7 小时前
服务异步通信
开发语言·后端·微服务·ruby
掘了7 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅7 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅8 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
爬山算法8 小时前
Hibernate(90)如何在故障注入测试中使用Hibernate?
java·后端·hibernate
崔庆才丨静觅8 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment8 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端