手把手教你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("兄嘚,你还没登录呢!"); } } }
??避坑指南??:
- 方法必须是
public
修饰——就像要把工具借给别人得先开门 - 调用非静态方法必须
new对象
——借锤子得先找到锤子主人 - 两个类要在同一个包,或者正确
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); } }
??问题分析??:
- 这种写法会导致??循环依赖??——就像两人互相抓着对方头发
- 内存中会创建无数个对象实例——系统直接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 "); // ? 报红! } }
??解决方法二选一??:
- 文件开头加:
import com.utils.StringUtil;
- 用全限定名:
com.utils.StringUtil.trim(" hello ")
说点项目组不让外传的
带过50+Java项目后总结的??三个黄金原则??:
- ??调用前先看权限??——就像进小区要刷卡,检查方法是不是
public
- ??非静态方法先new对象??——借东西得先找到物主
- ??跨类调用要防循环依赖??——避免A调B,B又调A的死循环
去年有个团队因为滥用静态方法调用,导致线上支付系统凌晨崩盘,直接损失30万订单。后来他们强制规定:??所有跨服务调用必须走接口契约??,这才稳住系统。
下次你要调用其他类方法时,不妨先画个调用关系图——就像玩《塞尔达》前先看地图,能少走80%的冤枉路!