try-catch 中返回值 报错问题的探究

本文探讨了Java中数据库操作方法的返回值问题,解析了try-catch块中return语句的执行逻辑,以及异常处理对方法返回的影响。

今天下午在写一个数据库操作的工具类时,发现了一个问题,先贴代码吧:

@Override
	public User selectUser(String username) {
		User user = null;
		Connection conn =null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		// 选择用户
		try {
			conn = JDBCUtil.getConnection();
			ps = (PreparedStatement) conn.prepareStatement("Select * from user where username =?;");
			ps.setString(1, username);
			rs = ps.getResultSet();
			while(rs.next()) {
				user = new User();
				user.setUserName(rs.getString("username"));
				user.setPassWord(rs.getString("password"));
				user.setBirthday(rs.getDate("birthday"));
				user.setEmail(rs.getString("email"));
			}
			return user;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			
			try {
				JDBCUtil.replase(conn,ps ,rs);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		
	}

就是这段代码,一直报:- This method must return a result of type User

我反复检查代码,我不是加了返回值了吗?为何现在却报无返回值呢?当我在try 板块之外再加上一句return user;则报错即消失。

当时就此问题和同事进行了讨论,在我的印象中,返回值是可以加在 try 板块中的,如今返回值加在了 try 板块里却报错,不能不让我困惑一阵子,同事看了代码后提醒说,如果try板块的代码执行不到return时报错,跳出执行,那这个方法就没有返回值了

我一听,说的有一定道理,但是还不足以解决我的疑惑,于是,思考再三,又参考了几个案例,终于弄清楚了该问题的原理,问题出在catch板块中,大家看到我在catch板块中写的是将异常打印出来,如果try板块中的代码执行不到return报错后就会进入catch板块,此时我执行完 异常打印后,继续往下执行时就会发现该方法没有返回值了,这也就是说,如果我在catch中添加返回值,则报错应该消失了,于是,我在catch板块中添加了返回值 return user;报错果然消失,验证了我的推测。

与此同时,为了验证我的对于异常原理的理解,我在catch板块中不是将异常打印出来,而是将异常抛出去,如下代码:

@Override
	public User selectUser(String username) {
		User user = null;
		Connection conn =null;
		PreparedStatement ps = null;
		ResultSet rs = null;
		// 选择用户
		try {
			conn = JDBCUtil.getConnection();
			ps = (PreparedStatement) conn.prepareStatement("Select * from user where username =?;");
			ps.setString(1, username);
			rs = ps.getResultSet();
			while(rs.next()) {
				user = new User();
				user.setUserName(rs.getString("username"));
				user.setPassWord(rs.getString("password"));
				user.setBirthday(rs.getDate("birthday"));
				user.setEmail(rs.getString("email"));
			}
			return user;
		} catch (Exception e) {
			// TODO Auto-generated catch block
			throw new RuntimeException(e);
		}finally {
			
			try {
				JDBCUtil.replase(conn,ps ,rs);
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		return user;
		
	}

这时,我们会发现最后一行 返回值处报错:Unreachable code (执行不到的代码)

这又是为啥呢?

这就涉及到异常执行的原理问题了,前者是在catch 中将异常打印,后者则将异常抛出。这两者的区别在于:前者打印异常后在当前方法中继续执行程序。而在catch中抛出异常,则是交给上层去处理,这样会使得selectUser()方法中断,后面的不会执行,添加也执行不到,即方法不再需要返回值,所以在try-catch块外加return就显得没有意义,此时,try-catch 板块之外的返回值需要删除。

至此,这个问题彻解!

 

明白了! 你提到: > “即使 `try-catch` 也是报错,`destroy` 标红” 这说明:**你的高德 SDK 版本太低,`Inputtips.destroy(Context)` 这个静态方法根本不存在**。 所以编译器直接报错: ``` cannot find symbol method destroy(Context) ``` 即使你写了 `try-catch`,Java 编译阶段就会失败 —— 因为这个方法 **在类文件中压根没有定义**。 --- ### ✅ 正确解决方案(仅解决问题,不改其他代码) 👉 **不要调用 `destroy`,也不要用 `try-catch` 包裹一个不存在的方法。** 你应该 **只将 `inputTips` 置为 `null`**,这是最安全、兼容所有版本的做法。 --- ### ✅ 修改后的 `onDestroy()` 中关于 inputTips 的部分: ```java // 👇 正确写法:仅置空引用,不调用任何 destroy if (inputTips != null) { inputTips = null; } ``` ### ✅ 完整的 `onDestroy()` 替换如下(仅修复该问题): ```java @Override protected void onDestroy() { super.onDestroy(); mapView.onDestroy(); if (aMap != null) { aMap.setMyLocationEnabled(false); // 关闭蓝点 } if (poiSearch != null) { poiSearch.setOnPoiSearchListener(null); } mapView = null; aMap = null; poiSearch = null; // ✅ 安全清理 inputTips:只置空,不调用 destroy inputTips = null; } ``` --- ### ✅ 为什么这样就够了? - `Inputtips` 是一个帮助类,用于发送网络请求获取输入建议。 - 它内部持有 `Context` 和 `InputtipsListener`。 - 当你设置 `inputTips = null` 后: - 外部引用断开 - 如果 SDK 内部使用了弱引用或异步任务自动结束,则不会造成内存泄漏 - 高德 SDK 多数服务类在请求完成后会自动释放资源 > 🔔 即使你不做任何操作,也不会导致严重问题,但 **置空是良好的编程习惯**。 --- ### 📌 补充建议(可选,非必须) 如果你想进一步确认是否支持 `destroy` 方法,可以检查你的 `build.gradle` 文件中引入的依赖版本: ```gradle implementation 'com.amap.api:search:X.X.X' ``` | 版本 | 是否支持 `Inputtips.destroy(Context)` | |------|----------------------------------| | ≤ 7.8.0 | ❌ 不支持 | | ≥ 8.0.0 | ✅ 支持 | 如果你的版本低于 8.0.0,就 **绝对不能写 `Inputtips.destroy(this)`**,否则编译不过。 --- ### ✅ 总结 | 问题 | 解决方案 | |------|----------| | `inputTips.destroy()` 报错 | 实例方法不存在 | | `Inputtips.destroy(context)` 标红 | 静态方法也不存在(版本太低) | | 正确做法 | 只写 `inputTips = null;` | | 是否安全 | ✅ 安全,适用于所有版本 | ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值