从 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 方法的执行逻辑、参数机制和运行时结构。

相关推荐
刘一说1 小时前
Vue 动态路由参数丢失问题详解:为什么 `:id` 拿不到值?
前端·javascript·vue.js
熊猫钓鱼>_>2 小时前
动态网站发布部署核心问题详解
前端·nginx·容器化·网页开发·云服务器·静态部署
方也_arkling2 小时前
elementPlus按需导入配置
前端·javascript·vue.js
好好研究2 小时前
Spring Boot - Thymeleaf模板引擎
java·spring boot·后端·thymeleaf
爬山算法2 小时前
Hibernate(76)如何在混合持久化环境中使用Hibernate?
java·后端·hibernate
我的xiaodoujiao2 小时前
使用 Python 语言 从 0 到 1 搭建完整 Web UI自动化测试学习系列 44--将自动化测试结果自动推送至钉钉工作群聊
前端·python·测试工具·ui·pytest
她说..2 小时前
策略模式+工厂模式实现单接口适配多审核节点
java·spring boot·后端·spring·简单工厂模式·策略模式
沛沛老爹2 小时前
Web开发者转型AI:多模态Agent视频分析技能开发实战
前端·人工智能·音视频
csdn_aspnet2 小时前
ASP.NET 8 - Cookie 身份验证
后端·asp.net·cookie·.net8
David凉宸2 小时前
vue2与vue3的差异在哪里?
前端·javascript·vue.js