首页 > 趣闻 > 正文内容

手把手教你Java调用其他类方法:步骤与代码示例

趣闻2025-05-28 04:35:33

场景故事:电商系统突然崩溃为哪般?

上周有个学员半夜给我打电话:"老师!我们电商系统支付完不跳转,查了一天发现是OrderService调UserService的方法报空指针!" 我让他截个代码片段,好家伙,两个类互相调方法写得像蜘蛛网。今天就拿这个真实案例,带你用??场景化思维??拆解问题。


一、基础场景:用户登录验证

??需求??:在OrderController中调用UserService的登录验证方法

java复制
// 用户服务类(隔壁老王家的工具)  
public class UserService {  
    public boolean checkLogin(String userId) {  
        // 实际开发这里要查数据库  
        return !userId.isEmpty();  
    }  
}  

// 订单控制器(你家客厅的遥控器)  
public class OrderController {  
    public void createOrder(String userId) {  
        // 关键步骤1:new个对象才能用人家方法  
        UserService userService = new UserService();  
        
        // 关键步骤2:拿着遥控器按按钮  
        if (userService.checkLogin(userId)) {  
            System.out.println("用户验证通过,开始创建订单");  
        } else {  
            System.out.println("兄嘚,你还没登录呢!");  
        }  
    }  
}  

??避坑指南??:

  1. 方法必须是public修饰——就像要把工具借给别人得先开门
  2. 调用非静态方法必须new对象——借锤子得先找到锤子主人
  3. 两个类要在同一个包,或者正确import——不然就像去邻居家借酱油却走错单元楼

二、进阶场景:跨类调用静态方法

??突发需求??:要在10个地方调用计算运费的公式方法

java复制
// 运费工具类(小区里的共享计算器)  
public class ShippingUtils {  
    // static修饰:谁都能用,不用找主人  
    public static double calculateFee(double weight) {  
        return weight * 5 + 10; // 基础运费公式  
    }  
}  

// 订单详情页(你家厨房的电子秤)  
public class OrderDetailPage {  
    public void showShippingInfo() {  
        // 直接类名.方法名调用  
        double fee = ShippingUtils.calculateFee(2.5);  
        System.out.println("运费:" + fee + "元");  
    }  
}  

// 购物车页面(客厅的茶几)  
public class ShoppingCart {  
    public void refreshTotal() {  
        // 同一个方法被多处调用  
        double fee = ShippingUtils.calculateFee(3.8);  
        System.out.println("预估运费:" + fee);  
    }  
}  

??为什么用静态方法??:

  • 就像小区里的公共饮水机,随用随取不占自家空间
  • 但注意!频繁修改静态方法会导致??牵一发而动全身??
  • 适合工具类方法:比如日期转换、数学计算

三、高难度场景:类之间互相调用

??真实事故还原??:UserService和OrderService互调死循环

java复制
// 用户服务类  
public class UserService {  
    // 错误示范:直接new对方类  
    OrderService orderService = new OrderService();  
    
    public void showUserOrders(String userId) {  
        // 调用订单服务  
        orderService.getOrdersByUser(userId);  
    }  
}  

// 订单服务类  
public class OrderService {  
    // 错误示范:又new回来  
    UserService userService = new UserService();  
    
    public void validateOrder(String userId) {  
        // 调用用户服务  
        userService.checkUserStatus(userId);  
    }  
}  

??问题分析??:

  1. 这种写法会导致??循环依赖??——就像两人互相抓着对方头发
  2. 内存中会创建无数个对象实例——系统直接OOM崩溃

??正确解决方案??:

java复制
// 用Spring框架的依赖注入(高级玩法)  
@Service  
public class UserService {  
    @Autowired  // 让框架自动装配  
    OrderService orderService;  
    
    public void showUserOrders(String userId) {  
        orderService.getOrdersByUser(userId);  
    }  
}  

// 或者用方法参数传递(基础解法)  
public class OrderService {  
    public void validateOrder(UserService userService, String userId) {  
        userService.checkUserStatus(userId);  
    }  
}  

四、实战场景:支付接口调第三方SDK

??真实项目代码??:调用支付宝验证接口

java复制
// 第三方支付工具类(别人家的快递柜)  
public class AlipayUtil {  
    // SDK规定必须用静态方法  
    public static boolean verifyPayment(String tradeNo) {  
        // 实际这里要调用HTTPS接口  
        return tradeNo.startsWith("2023");  
    }  
}  

// 自家支付处理器(你的手机)  
public class PaymentHandler {  
    public void processPayment(String orderId) {  
        // 调用静态方法验证  
        boolean isPaid = AlipayUtil.verifyPayment(orderId);  
        
        if (isPaid) {  
            System.out.println("微信到账100万元!");  
            updateOrderStatus(orderId);  
        }  
    }  
    
    private void updateOrderStatus(String orderId) {  
        // 调用自家数据库方法  
        OrderDAO orderDAO = new OrderDAO();  
        orderDAO.markAsPaid(orderId);  
    }  
}  

??重要经验??:

  • 调用第三方类方法要??先看文档??——就像用新家电要先看说明书
  • 静态方法调用注意??线程安全??——别同时挤爆人家接口
  • 非静态方法调用要处理??异常捕获??——万一对方方法抛异常呢?

高频踩坑现场直播

??案例1??:调用方法总是报NullPointerException

java复制
public class CouponService {  
    public void applyCoupon(String code) {  
        // 忘记new对象直接调用  
        UserService userService; // 只有声明没初始化  
        userService.checkVipLevel(); // ? 此处爆炸!  
    }  
}  

??急救方案??:

  • 在方法内初始化:UserService userService = new UserService();
  • 或者通过构造函数注入(推荐)

??案例2??:跨包调用找不到类

java复制
// com.utils.StringUtil 工具类  
package com.utils;  
public class StringUtil {  
    public static String trim(String str) {  
        return str.trim();  
    }  
}  

// com.web.controller.UserController  
package com.web.controller;  
public class UserController {  
    public void processInput() {  
        // 忘记导包  
        String result = StringUtil.trim(" hello "); // ? 报红!  
    }  
}  

??解决方法二选一??:

  1. 文件开头加:import com.utils.StringUtil;
  2. 用全限定名:com.utils.StringUtil.trim(" hello ")

说点项目组不让外传的

带过50+Java项目后总结的??三个黄金原则??:

  1. ??调用前先看权限??——就像进小区要刷卡,检查方法是不是public
  2. ??非静态方法先new对象??——借东西得先找到物主
  3. ??跨类调用要防循环依赖??——避免A调B,B又调A的死循环

去年有个团队因为滥用静态方法调用,导致线上支付系统凌晨崩盘,直接损失30万订单。后来他们强制规定:??所有跨服务调用必须走接口契约??,这才稳住系统。

下次你要调用其他类方法时,不妨先画个调用关系图——就像玩《塞尔达》前先看地图,能少走80%的冤枉路!

搜索