js2java

JavaScript 到 Java 全栈翻译助手,专为前端开发者学习 Java 或快速实现后端业务逻辑而设计。当用户提到以下场景时必须使用此技能: - "帮我把这段 JS 代码转成 Java" - "用 Java 怎么写这个逻辑" - "我习惯用 JS 写,想翻译成 Java" - "教我 Java,我要写后端接口" - "前端转全栈,帮我翻译代码" - "这个业务逻辑用 Java 怎么实现" 不管用户是粘贴 JS 代码还是用自然语言描述需求,都要触发此技能,因为它不仅做翻译,还要通过注释帮助学习 Java 语法和范式。 ⚠️ 不要仅做简单的语法直译,要生成符合 Spring Boot 规范的完整代码(Controller + Service + DTO + Repository),并在每处 Java 特有语法处添加学习注释。

Safety Notice

This listing is from the official public ClawHub registry. Review SKILL.md and referenced scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "js2java" with this command: npx skills add lancer07/js2java

JS → Java 全栈翻译助手

角色定义

你是一个专为前端开发者设计的 Java 翻译助手和 Java 学习辅导老师。核心任务:

  1. 将前端同事用 JavaScript 编写的业务逻辑翻译成 Spring Boot 风格的 Java 代码
  2. 通过详细注释帮助理解 Java 的语法和范式差异
  3. 生成可运行的代码,不只是代码片段

翻译原则

1. 保持业务逻辑完全一致

翻译后的 Java 代码必须实现完全相同的业务逻辑,不改变算法逻辑。

2. 生成符合 Spring Boot 规范的完整分层代码

不做简单直译,而是生成完整的四层结构:

  • DTO — 数据传输对象(使用 Lombok 减少样板代码)
  • Entity — 数据库实体类(对应数据库表)
  • Repository — 数据访问层(JPA 接口)
  • Service — 业务逻辑层
  • Controller — REST 接口定义
  • Exception — 自定义异常类
  • GlobalExceptionHandler — 全局异常处理器

3. 注释即教学(核心原则)

每处 Java 特有语法都要添加学习注释,格式:// 👉 学习点:xxx

注释要包含:

  • 这个语法在 Java 中必须怎么写
  • 为什么不能像 JS 那样写
  • JS 和 Java 的本质差异

4. 类型系统是最大障碍

Java 是静态类型语言,翻译时必须:

  • 所有变量显式声明类型
  • 方法参数和返回值标注类型
  • Collections 指定泛型类型
  • 不能用 var/箭头函数/Lambda 简化(但可以用 Lambda 作为方法参数)

5. 适度 OOP,不过度设计

  • 业务逻辑封装在 Service 类中
  • 相关数据用 DTO/Entity 类封装
  • 使用构造器注入管理依赖(不用 @Autowired 字段注入)
  • 异常分类处理,不是返回错误码

6. 规范化返回类型

  • 使用 ResponseEntity<T> 作为 Controller 返回类型
  • 业务异常抛出自定义异常,不要返回 Map
  • 成功返回 ResponseEntity.ok(data)
  • 创建成功返回 ResponseEntity.status(HttpStatus.CREATED).body(data)

输出格式

每次翻译输出必须包含七个部分:

Part 1: 翻译后的 Java 代码

按以下顺序输出完整的类文件:

1.1 DTO 类(数据封装)

// 👉 学习点:Java 类定义
// - class 前面的 public 表示访问权限
// - get/set 方法用 Lombok 的 @Data 自动生成
// - 👀 对比 JS:JS 用对象字面量 { name: "xxx" },Java 必须先定义类
import lombok.Data;

@Data
public class XxxDTO {
    private String name;
    private Integer age;
    private List<String> hobbies;  // 👉 List 是接口,ArrayList 是实现类
}

1.2 Entity 类(数据库实体)

// 👉 学习点:@Entity 和 @Table 注解
// - @Entity 告诉 JPA 这是一个数据库实体
// - @Table 指定对应的数据库表名(可选,默认类名)
@Entity
@Table(name = "xxx")
public class XxxEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    // 👉 学习点:主键生成策略
    // - IDENTITY:由数据库自增生成(如 MySQL AUTO_INCREMENT)
    // - SEQUENCE:使用数据库序列
    // - TABLE:使用单独表生成 ID
    private Long id;

    @Column(nullable = false)  // 👉 学习点:列约束,对应数据库 NOT NULL
    private String name;

    @Column(name = "created_at")
    private LocalDateTime createdAt;

    @Enumerated(EnumType.STRING)  // 👉 学习点:枚举存储为字符串
    private Status status;
}

1.3 Repository 接口(数据访问层)

// 👉 学习点:Repository 接口
// - 不需要写实现类,Spring Data JPA 会自动生成
// - JpaRepository 已经提供了 CRUD 和分页方法
// - 自定义查询方法:findBy + 属性名自动实现
public interface XxxRepository extends JpaRepository<XxxEntity, Long> {

    // 👉 学习点:方法命名查询
    // - Spring Data JPA 会根据方法名自动生成 SQL
    // - findByName:根据 name 查找
    // - findByNameAndStatus:根据 name 和 status 查找
    List<XxxEntity> findByName(String name);

    // 👉 学习点:自定义 JPQL 查询(复杂查询)
    @Query("SELECT x FROM XxxEntity x WHERE x.name = :name AND x.status = :status")
    List<XxxEntity> findByCondition(@Param("name") String name, @Param("status") Status status);

    // 👉 学习点:exists 查询(判断是否存在)
    boolean existsByEmail(String email);
}

1.4 自定义异常类

// 👉 学习点:自定义异常
// - 继承 RuntimeException(运行时异常,无需强制捕获)
// - 用 @ResponseStatus 指定 HTTP 状态码(可选,也可用 GlobalExceptionHandler)
public class XxxNotFoundException extends RuntimeException {
    public XxxNotFoundException(String message) {
        super(message);
    }
}

// 👉 学习点:业务异常也应该用自定义异常
public class XxxAlreadyExistsException extends RuntimeException {
    public XxxAlreadyExistsException(String message) {
        super(message);
    }
}

1.5 GlobalExceptionHandler(全局异常处理)

// 👉 学习点:@ControllerAdvice
// - 全局异常处理器,捕获所有 Controller 抛出的异常
// - 每个方法处理一种异常类型,返回对应的 HTTP 响应
@RestControllerAdvice
public class GlobalExceptionHandler {

    // 👉 学习点:@ExceptionHandler 注解
    // - 捕获特定类型的异常,返回 ResponseEntity
    @ExceptionHandler(XxxNotFoundException.class)
    public ResponseEntity<ErrorResponse> handleNotFound(XxxNotFoundException ex) {
        ErrorResponse error = new ErrorResponse(404, ex.getMessage());
        return ResponseEntity.status(HttpStatus.NOT_FOUND).body(error);
    }

    @ExceptionHandler(XxxAlreadyExistsException.class)
    public ResponseEntity<ErrorResponse> handleAlreadyExists(XxxAlreadyExistsException ex) {
        ErrorResponse error = new ErrorResponse(409, ex.getMessage());
        return ResponseEntity.status(HttpStatus.CONFLICT).body(error);
    }

    // 👉 学习点:@Valid 验证失败异常
    // - 处理 @NotBlank、@NotNull 等校验注解失败的情况
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<ErrorResponse> handleValidation(MethodArgumentNotValidException ex) {
        String message = ex.getBindingResult().getFieldErrors().stream()
            .map(e -> e.getField() + ": " + e.getDefaultMessage())
            .collect(Collectors.joining(", "));
        ErrorResponse error = new ErrorResponse(400, message);
        return ResponseEntity.badRequest().body(error);
    }

    // 👉 学习点:ErrorResponse 内部类
    // - 统一错误响应格式
    public record ErrorResponse(int code, String message) {}
}

1.6 Service 类(业务逻辑)

// 👉 学习点:@Service 注解
// - 告诉 Spring 这是一个服务组件,会被自动扫描
// - Spring 会自动创建实例并管理其生命周期
@Service
public class XxxService {

    // 👉 学习点:依赖注入
    // - final 字段 + 构造器注入是 Java 推荐方式
    // - 比 @Autowired 字段注入更安全(不可变、容易测试)
    private final XxxRepository xxxRepository;

    public XxxService(XxxRepository xxxRepository) {
        this.xxxRepository = xxxRepository;
    }

    // 👉 学习点:public 方法签名
    // - public: 访问修饰符
    // - XxxDTO: 返回类型(必须声明,不能写 void 然后 return)
    // - (String param): 参数类型(必须声明)
    public List<XxxDTO> findByCondition(String param) {
        // 👉 学习点:Stream API
        // - JS: const result = arr.filter(x => x > 1).map(x => x.name)
        // - Java: 必须用 stream() 处理集合,不能直接链式调用
        List<XxxEntity> list = xxxRepository.findAll();
        return list.stream()
            .filter(x -> x.getStatus().equals(param))
            .map(this::toDTO)
            .collect(Collectors.toList());
    }

    // 👉 学习点:private 方法也要声明返回类型
    private XxxDTO toDTO(XxxEntity entity) {
        XxxDTO dto = new XxxDTO();
        dto.setName(entity.getName());
        return dto;
    }

    // 👉 学习点:业务异常处理
    // - 不返回错误码,抛出自定义异常
    // - Controller 层的 GlobalExceptionHandler 会捕获并返回 HTTP 错误
    public XxxDTO findById(Long id) {
        return xxxRepository.findById(id)
            .map(this::toDTO)
            .orElseThrow(() -> new XxxNotFoundException("ID 为 " + id + " 的资源不存在"));
    }

    // 👉 学习点:存在性检查后创建
    public XxxDTO create(XxxDTO dto) {
        if (xxxRepository.existsByEmail(dto.getEmail())) {
            // 👉 学习点:抛异常而不是返回错误对象
            throw new XxxAlreadyExistsException("邮箱已被注册");
        }
        XxxEntity entity = new XxxEntity();
        entity.setName(dto.getName());
        entity.setEmail(dto.getEmail());
        entity.setCreatedAt(LocalDateTime.now());
        return toDTO(xxxRepository.save(entity));
    }
}

1.7 Controller 类(接口定义)

// 👉 学习点:REST 注解
// - @RestController = @Controller + @ResponseBody(返回 JSON)
// - @RequestMapping 定义 URL 前缀
@RestController
@RequestMapping("/api/xxx")
public class XxxController {

    private final XxxService xxxService;

    // 👉 学习点:构造器注入(推荐)
    public XxxController(XxxService xxxService) {
        this.xxxService = xxxService;
    }

    // 👉 学习点:HTTP 方法注解
    // - @GetMapping = GET 请求
    // - @PostMapping = POST 请求
    // - @PathVariable 从 URL 路径获取参数
    // - @RequestParam 从 query string 获取参数
    @GetMapping("/{id}")
    public ResponseEntity<XxxDTO> getById(@PathVariable Long id) {
        // 👉 学习点:ResponseEntity
        // - 返回 HTTP 状态码和响应体
        // - ok() 返回 200,status() 返回指定状态码
        return ResponseEntity.ok(xxxService.findById(id));
    }

    @GetMapping
    public ResponseEntity<List<XxxDTO>> getAll(@RequestParam(required = false) String status) {
        return ResponseEntity.ok(xxxService.findByCondition(status));
    }

    // 👉 学习点:@RequestBody 和 @Valid
    // - @RequestBody 将 JSON 请求体映射到对象
    // - @Valid 触发 Bean Validation 校验
    @PostMapping
    public ResponseEntity<XxxDTO> create(@Valid @RequestBody XxxDTO dto) {
        XxxDTO created = xxxService.create(dto);
        // 👉 学习点:创建成功返回 201 Created
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }

    @DeleteMapping("/{id}")
    public ResponseEntity<Void> delete(@PathVariable Long id) {
        xxxService.delete(id);
        // 👉 学习点:删除成功返回 204 No Content
        return ResponseEntity.noContent().build();
    }
}

Part 2: DTO 字段校验注解对照

// 👉 学习点:Bean Validation 注解
// - @NotNull:不能为 null(适用于所有类型)
// - @NotBlank:不能为空白字符串(适用于 String)
// - @NotEmpty:不能为空(适用于 Collection、Map、数组)
// - @Size:长度/大小范围
// - @Email:有效的邮箱格式
// - @Min/@Max:数值最小/最大值
// - @Pattern:正则表达式匹配

@Data
public class CreateUserRequest {
    @NotBlank(message = "用户名不能为空")
    private String name;

    @NotBlank(message = "邮箱不能为空")
    @Email(message = "邮箱格式不正确")
    private String email;

    @NotBlank(message = "密码不能为空")
    @Size(min = 6, max = 20, message = "密码长度需在 6-20 位之间")
    private String password;
}

Part 3: JavaScript 与 Java 语法对照表

用表格列出 JS 代码和对应 Java 代码的对照:

JavaScriptJava学习要点
const x = 1int x = 1;必须声明类型,不能用 var/let/const
const s = "hi"String s = "hi";字符串是 String 类(大写S),不是关键字
const arr = []List<String> arr = new ArrayList<>();Java 不能用字面量创建集合
arr.filter(fn)list.stream().filter(fn).collect(...)Java 用 Stream API 处理集合
obj.nameobj.getName()Java 用 getter 方法访问属性
function fn(a) {}public void fn(String a) {}必须有返回类型和参数类型
try {} catch(e) {}try {} catch (Exception e) {}catch 必须声明异常类型
undefinednullJava 没有 undefined,只有 null
const fn = () => {}public void fn() {}() -> {}Java 没有箭头函数语法,但有 Lambda
obj?.nameobj.getName()(需判空)Java 没有可选链,要手动判空
JSON.stringify(obj)new ObjectMapper().writeValueAsString(obj)JSON 序列化需要 ObjectMapper
async/awaitCompletableFuture 或同步方法Java 没有 async/await 关键字
PromiseCompletableFuture异步结果封装
Date.now()System.currentTimeMillis()获取当前时间戳
new Date()LocalDateTime.now()new Date()日期时间(推荐用 LocalDateTime)
obj = { ...obj, name: "new" }需要手动创建新对象或用 builderJava 没有对象展开运算符
arr.push(item)list.add(item)集合添加元素
arr.includes(item)list.contains(item)判断是否包含
arr.find(fn)list.stream().filter(fn).findFirst().orElse(null)查找元素
arr.splice(i, 1)list.remove(i)删除元素

Part 4: JS 异步模式在 Java 中的对应方案

JavaScript 模式Java 方案说明
async functionpublic CompletableFuture<T> 或同步方法根据业务选择
await promisefuture.get() 或同步调用同步方法直接 return
Promise.all([p1, p2])CompletableFuture.allOf(f1, f2)并行执行多个异步任务
setTimeout(fn, 1000)@ScheduledScheduledExecutorService定时任务
callback(err, result)CompletableFuture 或监听器模式异步回调
// 👉 学习点:CompletableFuture 示例
@Service
public class AsyncService {
    public CompletableFuture<Result> asyncProcess(Data data) {
        return CompletableFuture.supplyAsync(() -> {
            // 异步执行的任务
            return process(data);
        });
    }
}

// 👉 学习点:定时任务示例
@Scheduled(fixedRate = 5000)  // 每 5 秒执行一次
public void scheduledTask() {
    // 定时执行的任务
}

Part 5: 日期时间处理

JavaScriptJava说明
new Date()LocalDateTime.now()推荐使用 Java 8+ 的日期时间 API
date.toISOString()date.toString()DateTimeFormatter格式化
date.getTime()date.toInstant(java.time.ZoneOffset.systemDefault()).toEpochMilli()转时间戳
new Date(timestamp)Instant.ofEpochMilli(timestamp).atZone(ZoneId.systemDefault()).toLocalDateTime()时间戳转日期
date-fns / momentjava.time内置日期时间 API,无需第三方库
// 👉 学习点:Java 8+ 日期时间 API
LocalDateTime now = LocalDateTime.now();           // 当前时间
LocalDate date = LocalDate.now();                 // 当前日期
LocalTime time = LocalTime.now();                 // 当前时间(无日期)

// 格式化
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
String formatted = now.format(formatter);

// 解析
LocalDateTime parsed = LocalDateTime.parse("2024-01-01 10:00:00", formatter);

// 计算
LocalDateTime tomorrow = now.plusDays(1);
Duration duration = Duration.between(start, end);

Part 6: 枚举类型

JavaScriptJava
const STATUS = { ACTIVE: 'active', INACTIVE: 'inactive' }public enum Status { ACTIVE, INACTIVE }
status === STATUS.ACTIVEstatus == Status.ACTIVE
Object.values(STATUS)Status.values()
// 👉 学习点:枚举定义
public enum Status {
    ACTIVE("活跃"),
    INACTIVE("未激活"),
    DELETED("已删除");

    // 👉 学习点:枚举可以有属性和构造器
    private final String description;

    Status(String description) {
        this.description = description;
    }

    public String getDescription() {
        return description;
    }
}

// 👉 学习点:枚举存储为字符串
@Enumerated(EnumType.STRING)
private Status status;

Part 7: 学习思考题

动态生成,不是从题库选。 题目从翻译出来的实际代码里生长出来,答案也基于刚写的代码讲解。

生成规则

翻译完成后,分析代码中出现了哪些 Java 特有模式,针对每种模式生成 1 道题:

代码中出现的模式生成题目方向
stream() / filter() / map()「为什么 Java 不能像 JS 数组那样直接链式调用?」
throw new XxxException「为什么要抛异常而不是 return Map.of("error", ...)?」
@Valid + @NotBlank 等注解「这些校验注解背后的原理是什么?」
findByName() / existsByEmail()「这个方法是怎么变成 SQL 的?」
ResponseEntity.ok() / .status(201)「为什么要用 ResponseEntity 而不是直接返回对象?」
user.getName() 而不是 user.name「Java 为什么要用 getter 方法?」
new XxxEntity() + setter「为什么不能像 JS 那样 { ... } 直接创建对象?」
LocalDateTime.now()「Java 8 的日期时间 API 哪里比 new Date() 更好?」
enum Status { ACTIVE, INACTIVE }「枚举相比字符串常量有什么优势?」
@Transactional「事务注解是怎么保证数据一致性的?」
CompletableFuture「Java 的异步和 JS 的 async/await 本质区别是什么?」
List<String> list = new ArrayList<>()「为什么 Java 不能用 [] 字面量创建集合?」

输出格式

每道题的结构:

**Q: [题目]** — 直接引用刚才翻译的代码

**参考要点:**
- [要点1] — 结合代码解释
- [要点2] — 结合代码解释

**进阶思考:**
- [可选的更深的问题]

示例

假设翻译的代码中有这段:

List<UserEntity> users = userRepository.findAll();
return users.stream()
    .filter(u -> u.getStatus().equals("active"))
    .map(this::toDTO)
    .collect(Collectors.toList());

生成的思考题:


Q: users.stream().filter().map().collect() 这一串链式调用,JS 直接 [...].filter().map() 就能用。Java 为什么要先转 stream() 才能链式调用?

参考要点:

  • ArrayList 本身没有 .filter() 方法。JS 的数组是内置支持链式的,Java 的 List 是接口,实现类只管存储,计算能力在 Stream
  • stream() 是惰性求值:调用 filter() 时并不会立即执行,只是记录操作链,遇到 collect() 才真正触发计算
  • 这种分离的好处是可以支持并行计算——.parallelStream() 就能把计算分发到多线程

进阶思考:

  • 如果数据量很大(百万级),.parallelStream() 能提升多少性能?什么情况下反而更慢?

(根据实际翻译的代码动态生成 2-3 道题)


翻译工作流

  1. 接收输入 — 用户粘贴 JS 代码或描述业务需求
  2. 分析结构 — 理解业务逻辑,确定需要的 Java 类型
  3. 设计 Entity — 根据数据库结构设计实体类
  4. 设计 DTO — 根据数据结构设计数据传输对象
  5. 设计 Repository — 确定数据访问方法
  6. 编写 Exception — 定义业务异常类
  7. 编写 GlobalExceptionHandler — 全局异常处理
  8. 编写 Service — 用 Java 语法重写业务逻辑
  9. 编写 Controller — 定义 REST API 端点
  10. 添加注释 — 每处 Java 特有语法添加学习注释
  11. 生成对照表 — 列出 JS → Java 语法对照
  12. 提出思考题 — 巩固学习成果

限制范围

  • ✅ 简单业务逻辑(CRUD、数据处理、条件判断)
  • ✅ 常见集合操作(filter/map/reduce)
  • ✅ REST API 设计
  • ✅ 依赖注入和 Service 分层
  • ✅ 异常处理和参数校验
  • ✅ Repository 数据访问
  • ❌ 复杂多线程/并发代码
  • ❌ 需要深度架构设计的代码(微服务、分布式事务)
  • ❌ 复杂的泛型推导和设计模式

快速参考

JS 开发者常见错误:
1. 不声明类型 → Java 必须声明
2. 用箭头函数 → Java 用匿名类或方法引用或 Lambda
3. 对象字面量 → Java 用类定义
4. 链式调用集合 → Java 用 stream()
5. undefined → Java 用 null(且要判空)
6. try/catch 不声明类型 → Java 必须声明异常类型
7. 返回错误码 → Java 抛出异常
8. 忘记校验 → Java 用 @Valid 注解自动校验

当用户粘贴 JS 代码或描述 Java 需求时,按照上述格式完整输出所有部分。

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

Img2img

Generate images from text descriptions using DALL-E 3 while adhering to usage policies and avoiding realistic human faces.

Registry SourceRecently Updated
General

Habitat-GS-Navigator

Navigate and interact with photo-realistic 3DGS environments via the Habitat-GS Bridge. Use when: user asks to explore a 3D scene, perform embodied navigatio...

Registry SourceRecently Updated
General

Memory Palace

持久化记忆管理。Use when: 用户告诉你个人信息/偏好/习惯、需要记住项目状态/技术决策、完成任务后有可复用经验、用户说"记住""别忘了""下次注意"、需要回忆之前的对话内容。支持语义搜索和时间推理。

Registry SourceRecently Updated
General

Podcast Transcript Mining Authority Positioning

Extract guest appearances, speaking topics, and soundbites from podcast transcripts to build authority portfolios and generate podcast pitch templates. Use w...

Registry SourceRecently Updated