警惕在类中.方法外.书写操作语句

本文探讨了Java编程中类变量赋值的规范,特别关注于类外赋值导致的编译错误,并提供了正确的解决方案。通过实例演示,帮助开发者避免常见错误,提升代码质量。
 

        最近在做android程序的开发,大家都知道android程序使用的是java语言,所以在开发过程中一个要按照java语言书写规范进行编码。

        由于本人的入门编程语言是C语言,便养成了编码随意的坏毛病。所以今天遇到了一个本质很简单,但是却耗费了我很长时间才解决的问题:在类中/方法外,书写了操作语句。

        众所周知,java是纯面向对象的编程语言,所以程序的实现都是基于一个个的类。类中有两大部分,一部分是变量的声明,一部分是方法的实现。而错误往往发生在类变量的赋值上,因为类变量的赋值操作并非是简简单单一个等号就可以解决的,而是用其封装的方法进行赋值,如果赋值操作是在方法外的,那么程序编译就会报错。下面来举例说明之。

        如果这样写,程序在编译过程中就会报错:

 

 

public class a

    {

    //变量声明部分

    int a = 4 ;

    Paint paint = new Paint();

    paint.setColor(Color.BLUE);

    //方法声明部分

    public void b()

    {

         //...

    };

}

 

        我们看到:“paint.setColor(Color.BLUE);”语句发生了错误,原因就是这是一条操作语句,而它并没有在方法中,所以程序报错,报错信息如下:

 

 

Multiple markers at this line

       - Syntax error on token "setColor", Identifier expected after this

        token

       - Syntax error on token ".", ... expected

        如果经过如下修改(将报错的语句放入到方法b中),则可以通过编译:

 

 

        归根结底是java语言掌握的不够牢固所致,我们以前用惯了C语言,声明完变量后就想对其进行赋值,殊不知赋值语句在方法外是一种错误的写法,我们可以在类中书写一个init()方法,做为声明变量的初始化。

        很傻很天真的一个错误,写出来的目的是给自己做一个警惕,如果能给读者你一些启示那便是再好不过的事情啦,大家一起加油。

 

 

 

 

<think>我们正在讨论SQL中WHERE子句能否使用列别名的问题。根据提供的引用内容,答案很明确:**在标准SQL中,WHERE子句不能直接使用SELECT列表中定义的列别名**。原因与SQL语句的执行顺序有关。 ### 原因分析 1. **SQL执行顺序**(非书写顺序): - `FROM` → `WHERE` → `SELECT` → `GROUP BY` → `HAVING` → `ORDER BY` - 别名是在`SELECT`阶段定义的,而`WHERE`子句在`SELECT`之前执行。当执行`WHERE`时,别名尚未生效,因此无法识别。 2. **错误示例**(引用[2]): ```sql SELECT AVG(a) AS bb FROM table WHERE bb > 10; -- 报错:bb列不存在 ``` ### 解决方案 #### 方法1:直接使用原始表达式(适合简单计算) ```sql SELECT AVG(a) AS bb FROM table WHERE AVG(a) > 10; ``` > ⚠️ 注意:聚合函数(如`AVG()`)在`WHERE`中会报错,此时必须用`HAVING`或子查询。 #### 方法2:通过派生表(子查询)使用别名(通用方案) ```sql SELECT cc.bb FROM (SELECT AVG(a) AS bb FROM table) AS cc WHERE cc.bb > 10; ``` - 原理:子查询先执行并生成别名,层查询再使用该别名。 #### 方法3:使用`HAVING`子句(仅限聚合函数过滤) ```sql SELECT AVG(a) AS bb FROM table HAVING bb > 10; ``` > 注意:`HAVING`在`SELECT`之后执行,可识别别名,但设计初衷是过滤分组(需配合`GROUP BY`)。单用时要警惕性能影响。 ### 特殊场景处理(引用[4]) 当别名涉及复杂计算(如地理距离公式)时,必须用派生表: ```sql SELECT SS.* FROM ( SELECT s.*, (2 * 6378.137 * ASIN(SQRT(...))) AS juli -- 复杂计算 FROM vip_stores AS s ) AS SS WHERE SS.juli < 5.0 -- 层使用别名过滤 ORDER BY SS.juli; ``` ### 总结对比 | 场景 | 可用方案 | 限制条件 | |--------------------|-----------------------------|-----------------------| | 简单列别名 | 原始表达式代替 | 表达式不宜过长 | | 聚合函数结果过滤 | `HAVING` 或 子查询 | `HAVING`可能误用 | | 复杂计算表达式 | 必须用派生表(子查询) | 无 | > 💡 最佳实践:当别名涉及复杂计算或聚合时,**优先使用派生表**,既清晰又避免重复计算。 --- ### 相关问题 1. **为什么`ORDER BY`可以使用别名而`WHERE`不能?** (提示:执行顺序差异) 2. **如何优化包含复杂计算的派生表查询性能?** (提示:考虑临时表或物化视图) 3. **MySQL 8.0+的通用表表达式(CTE)能否替代派生表解决别名问题?** (提示:`WITH`语句示例对比) 4. **哪些数据库支持在`WHERE`中使用列别名?** (提示:研究PostgreSQL/MSSQL的方言特性) [^1]: SQL查询执行流程解析 [^2]: WHERE子句与列别名的冲突案例 [^3]: 别名绑定时机解释 [^4]: 派生表解决复杂计算别名过滤</think>### SQL WHERE条件中能否使用列别名? **直接答案:在标准SQL中,WHERE子句不能直接使用SELECT列表中定义的列别名**。原因与SQL语句的执行顺序密切相关。 #### 核心原因:SQL执行顺序限制 1. **执行顺序**(关键路径): ```mermaid graph LR A[FROM/JOIN] --> B[WHERE] B --> C[SELECT 列计算与别名定义] C --> D[GROUP BY] D --> E[HAVING] E --> F[ORDER BY] ``` - **WHERE在SELECT之前执行**:当执行WHERE条件过滤时,SELECT阶段的列别名尚未生成(引用[1][^1][^2][^3])。 - 别名本质是结果集的"显示标签",而非物理列名。 2. **错误示例**: ```sql SELECT AVG(salary) AS avg_sal FROM employees WHERE avg_sal > 10000; -- 报错:列"avg_sal"不存在 ``` #### 解决方案(如何绕过限制) ##### 方法1:改用原始表达式 ```sql SELECT AVG(salary) AS avg_sal FROM employees WHERE AVG(salary) > 10000; -- 直接使用聚合函数 ``` > ⚠️ 限制:聚合函数需配合`HAVING`(见方法3),非聚合列可这样用 ##### 方法2:通过派生表(子查询) ```sql SELECT * FROM ( SELECT s.name, (s.math_score + s.english_score) AS total -- 子查询内定义别名 FROM students s ) AS subquery WHERE subquery.total > 180; -- 层使用别名 ``` - ✅ **最通用方案**:适用于所有复杂计算和聚合(引用[2][^2][^4]) - 原理:子查询先执行并生成别名,层WHERE再引用 ##### 方法3:用HAVING替代WHERE(仅限聚合函数) ```sql SELECT department, AVG(salary) AS avg_sal FROM employees GROUP BY department HAVING AVG(salary) > 10000; -- HAVING在SELECT后执行 ``` > 💡 注意:`HAVING`必须配合`GROUP BY`使用,且只适用于聚合结果过滤 #### 特殊场景:地理计算示例(引用[4]) ```sql SELECT SS.* FROM ( SELECT s.*, (2 * 6378.137 * ASIN(SQRT(...))) AS distance -- 复杂计算 FROM locations s ) AS SS WHERE SS.distance < 5.0 -- 成功使用别名 ORDER BY SS.distance; ``` #### 总结对比 | 方法 | 适用场景 | 优势 | 限制 | |--------------------|-------------------------|----------------------|-------------------| | **派生表(子查询)** | 所有复杂计算/聚合 | 100%兼容所有SQL | 语句稍复杂 | | **HAVING子句** | 聚合结果过滤 | 简洁 | 必须配合GROUP BY | | **原始表达式** | 简单非聚合列计算 | 无需嵌套 | 需重复书写表达式 | > 💡 **最佳实践**:当WHERE需要引用复杂计算列时,**优先使用派生表方案**,兼顾可读性与兼容性。 --- ### 相关问题 1. **为什么ORDER BY可以使用别名而WHERE不能?** (提示:执行顺序中`ORDER BY`在`SELECT`之后[^3]) 2. **如何在GROUP BY中使用列别名?** (提示:同样受执行顺序限制,需用派生表) 3. **MySQL 8.0的通用表表达式(CTE)能否解决此问题?** (提示:对比`WITH`子句和派生表性能) 4. **哪些数据库支持在WHERE中直接使用别名?** (提示:研究PostgreSQL/Microsoft SQL Server的方言特性) [^1]: WHERE子句执行时机早于别名定义 [^2]: 通过子查询包装实现别名访问 [^3]: 别名绑定在结果集生成阶段 [^4]: 派生表处理复杂计算场景
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值