精华内容
下载资源
问答
  • 拦截器(Interceptor)和过滤器(Filter)的执行顺序和区别

    一、引言

    本来想记录一下关于用户登陆和登陆之后的权限管理、菜单管理的问题,想到解决这个问题用到Interceptor,但想到了Interceptor,就想到了Filter,于是就想说一下它们的执行顺序和区别。关于Interceptor解决权限和菜单管理的问题,在放在下一篇写吧,就酱紫。

    二、区别

    1、过滤器(Filter)

    首先说一下Filter的使用地方,我们在配置web.xml时,总会配置下面一段设置字符编码,不然会导致乱码问题:

    <filter>
        <filter-name>encoding</filter-name>
        <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
        <init-param>
            <param-name>encoding</param-name>
            <param-value>UTF-8</param-value>
        </init-param>
        <init-param>
            <param-name>forceEncoding</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>
    
    <filter-mapping>
        <filter-name>encoding</filter-name>
        <servlet-name>/*</servlet-name>
    </filter-mapping>
    

    配置这个地方的目的,是让所有的请求都需要进行字符编码的设置,下面来介绍一下Filter。

    (1)过滤器(Filter):它依赖于servlet容器。它可以对几乎所有请求进行过滤,但是缺点是一个过滤器实例只能在容器初始化时调用一次。使用过滤器的目的,是用来做一些过滤操作,获取我们想要获取的数据,比如:在Javaweb中,对传入的request、response提前过滤掉一些信息,或者提前设置一些参数,然后再传入servlet或者Controller进行业务逻辑操作。通常用的场景是:在过滤器中修改字符编码(CharacterEncodingFilter)、在过滤器中修改HttpServletRequest的一些参数(XSSFilter(自定义过滤器)),如:过滤低俗文字、危险字符等。

    2、拦截器(Interceptor)

    拦截器的配置一般在SpringMVC的配置文件中,使用Interceptors标签,具体配置如下:

    <mvc:interceptors>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.LoginInterceptor"></bean>
        </mvc:interceptor>
        <mvc:interceptor>
            <mvc:mapping path="/**" />
            <bean class="com.scorpios.atcrowdfunding.web.AuthInterceptor"></bean>
        </mvc:interceptor>
    </mvc:interceptors>
    

    (2)拦截器(Interceptor):它依赖于web框架,在SpringMVC中就是依赖于SpringMVC框架。在实现上,基于Java的反射机制,属于面向切面编程(AOP)的一种运用,就是在service或者一个方法前,调用一个方法,或者在方法后,调用一个方法,比如动态代理就是拦截器的简单实现,在调用方法前打印出字符串(或者做其它业务逻辑的操作),也可以在调用方法后打印出字符串,甚至在抛出异常的时候做业务逻辑的操作。由于拦截器是基于web框架的调用,因此可以使用Spring的依赖注入(DI)进行一些业务操作,同时一个拦截器实例在一个controller生命周期之内可以多次调用。拦截器可以对静态资源的请求进行拦截处理。

    三、代码


    下面在一个项目中我们使用既有多个过滤器,又有多个拦截器,并观察它们的执行顺序:
    (1)第一个过滤器:

    public class TestFilter1 implements Filter {  
      
    		@Override
      	    protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
            //在DispatcherServlet之前执行  
    		System.out.println("############TestFilter1 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后  
            System.out.println("############TestFilter1 doFilter after############");  
        }  
    }  
    

    (2)第二个过滤器:

    public class TestFilter2 implements Filter {  
     
    	@Override
        protected void doFilter(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {  
    	    //在DispatcherServlet之前执行  
            System.out.println("############TestFilter2 doFilterInternal executed############");  
            filterChain.doFilter(request, response);  
            //在视图页面返回给客户端之前执行,但是执行顺序在Interceptor之后 
            System.out.println("############TestFilter2 doFilter after############");  
        }  
    }  
    

    (3)在web.xml中注册这两个过滤器:

    <!-- 自定义过滤器:testFilter1 -->   
    <filter>  
        <filter-name>testFilter1</filter-name>  
        <filter-class>com.scorpios.filter.TestFilter1</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>testFilter1</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    
    <!-- 自定义过滤器:testFilter2 -->   
    <filter>  
        <filter-name>testFilter2</filter-name>  
        <filter-class>com.scorpios.filter.TestFilter2</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>testFilter2</filter-name>  
        <url-pattern>/*</url-pattern>  
    </filter-mapping>  
    

    再定义两个拦截器:
    (4)第一个拦截器:

    public class BaseInterceptor implements HandlerInterceptor{  
         
        /** 
         * 在DispatcherServlet之前执行 
         * */  
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************BaseInterceptor preHandle executed**********");  
            return true;  
        }  
     
        /** 
         * 在controller执行之后的DispatcherServlet之后执行 
         * */  
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************BaseInterceptor postHandle executed**********");  
        }  
         
        /** 
         * 在页面渲染完成返回给客户端之前执行 
         * */  
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3)  
                throws Exception {  
            System.out.println("************BaseInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (5)第二个拦截器:

    public class TestInterceptor implements HandlerInterceptor {  
     
        public boolean preHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2) throws Exception {  
            System.out.println("************TestInterceptor preHandle executed**********");  
            return true;  
        }  
     
        public void postHandle(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, ModelAndView arg3) throws Exception {  
            System.out.println("************TestInterceptor postHandle executed**********");  
        }  
     
        public void afterCompletion(HttpServletRequest arg0, HttpServletResponse arg1, Object arg2, Exception arg3) throws Exception {  
            System.out.println("************TestInterceptor afterCompletion executed**********");  
        }  
    }  
    

    (6)、在SpringMVC的配置文件中,加上拦截器的配置:

    <!-- 拦截器 -->  
    <mvc:interceptors>  
        <!-- 对所有请求都拦截,公共拦截器可以有多个 -->  
        <bean name="baseInterceptor" class="com.scorpios.interceptor.BaseInterceptor" />  
    
        <mvc:interceptor> 
            <!-- 对/test.jsp进行拦截 -->       
            <mvc:mapping path="/test.jsp"/>  
            <!-- 特定请求的拦截器只能有一个 -->  
            <bean class="com.scorpios.interceptor.TestInterceptor" />  
        </mvc:interceptor>  
    </mvc:interceptors>  
    

    (7)、定义一个Controller控制器:

    package com.scorpios.controller;  
    import org.springframework.stereotype.Controller;  
    import org.springframework.web.bind.annotation.RequestMapping;  
    import org.springframework.web.servlet.ModelAndView;  
      
    @Controller  
    public class TestController {  
        @RequestMapping("/test")  
        public ModelAndView handleRequest(){  
            System.out.println("---------TestController executed--------");  
            return new ModelAndView("test");  
        }  
    }  
    

    (8)、测试结果:
    启动测试项目,地址如下:http://www.localhost:8080/demo,可以看到控制台中输出如下:
    这里写图片描述
    这就说明了过滤器的运行是依赖于servlet容器,跟springmvc等框架并没有关系。并且,多个过滤器的执行顺序跟xml文件中定义的先后关系有关。

    接着清空控制台,并访问:http://www.localhost:8080/test,再次看控制台的输出:
    这里写图片描述
    从这个控制台打印输出,就可以很清晰地看到有多个拦截器和过滤器存在时的整个执行顺序了。当然,对于多个拦截器它们之间的执行顺序跟在SpringMVC的配置文件中定义的先后顺序有关。

    四、总结


    对于上述过滤器和拦截器的测试,可以得到如下结论:

    • Filter需要在web.xml中配置,依赖于Servlet

    • Interceptor需要在SpringMVC中配置,依赖于框架

    • Filter的执行顺序在Interceptor之前,具体的流程见下图
      在这里插入图片描述

    • 两者的本质区别:拦截器(Interceptor)是基于Java的反射机制,而过滤器(Filter)是基于函数回调。从灵活性上说拦截器功能更强大些,Filter能做的事情,都能做,而且可以在请求前,请求后执行,比较灵活。Filter主要是针对URL地址做一个编码的事情、过滤掉没用的参数、安全校验(比较泛的,比如登录不登录之类),太细的话,还是建议用interceptor。不过还是根据不同情况选择合适的。

    展开全文
  • 关于sql和MySQL的语句执行顺序(必看!!!)

    万次阅读 多人点赞 2016-03-29 12:15:09
    目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及MySQL语句执行顺序: sql和mysql执行顺序,发现内部机制是一样的。最大区别是在别名的引用上。 一、sql执行顺序 (1)from (3)...

    今天遇到一个问题就是mysql中insert into 和update以及delete语句中能使用as别名吗?目前还在查看,但是在查阅资料时发现了一些有益的知识,给大家分享一下,就是关于sql以及MySQL语句执行顺序:

    sql和mysql执行顺序,发现内部机制是一样的。最大区别是在别名的引用上。 


    一、sql执行顺序 

    1. from 
    2. join 
    3. on 
    4. where 
    5. group by(开始使用select中的别名,后面的语句中都可以使用)
    6.  avg,sum.... 
    7. having 
    8. select 
    9. distinct 
    10. order by
    11. limit 


    从这个顺序中我们不难发现,所有的 查询语句都是从from开始执行的,在执行过程中,每个步骤都会为下一个步骤生成一个虚拟表,这个虚拟表将作为下一个执行步骤的输入。 


    第一步:首先对from子句中的前两个表执行一个笛卡尔乘积,此时生成虚拟表 vt1(选择相对小的表做基础表)。 
    第二步:接下来便是应用on筛选器,on 中的逻辑表达式将应用到 vt1 中的各个行,筛选出满足on逻辑表达式的行,生成虚拟表 vt2 。
    第三步:如果是outer join 那么这一步就将添加外部行,left outer jion 就把左表在第二步中过滤的添加进来,如果是right outer join 那么就将右表在第二步中过滤掉的行添加进来,这样生成虚拟表 vt3 。

    第四步:如果 from 子句中的表数目多余两个表,那么就将vt3和第三个表连接从而计算笛卡尔乘积,生成虚拟表,该过程就是一个重复1-3的步骤,最终得到一个新的虚拟表 vt3。 

    第五步:应用where筛选器,对上一步生产的虚拟表引用where筛选器,生成虚拟表vt4,在这有个比较重要的细节不得不说一下,对于包含outer join子句的查询,就有一个让人感到困惑的问题,到底在on筛选器还是用where筛选器指定逻辑表达式呢?on和where的最大区别在于,如果在on应用逻辑表达式那么在第三步outer join中还可以把移除的行再次添加回来,而where的移除的最终的。举个简单的例子,有一个学生表(班级,姓名)和一个成绩表(姓名,成绩),我现在需要返回一个x班级的全体同学的成绩,但是这个班级有几个学生缺考,也就是说在成绩表中没有记录。为了得到我们预期的结果我们就需要在on子句指定学生和成绩表的关系(学生.姓名=成绩.姓名)那么我们是否发现在执行第二步的时候,对于没有参加考试的学生记录就不会出现在vt2中,因为他们被on的逻辑表达式过滤掉了,但是我们用left outer join就可以把左表(学生)中没有参加考试的学生找回来,因为我们想返回的是x班级的所有学生,如果在on中应用学生.班级='x'的话,left outer join会把x班级的所有学生记录找回(感谢网友康钦谋__康钦苗的指正,所以只能在where筛选器中应用学生.班级='x' 因为它的过滤是最终的。 

    第六步:group by 子句将中的唯一的值组合成为一组,得到虚拟表vt5。如果应用了group by,那么后面的所有步骤都只能得到的vt5的列或者是聚合函数(count、sum、avg等)。原因在于最终的结果集中只为每个组包含一行。这一点请牢记。 

    第七步:应用cube或者rollup选项,为vt5生成超组,生成vt6. 
    第八步:应用having筛选器,生成vt7。having筛选器是第一个也是为唯一一个应用到已分组数据的筛选器。 
    第九步:处理select子句。将vt7中的在select中出现的列筛选出来。生成vt8. 

    第十步:应用distinct子句,vt8中移除相同的行,生成vt9。事实上如果应用了group by子句那么distinct是多余的,原因同样在于,分组的时候是将列中唯一的值分成一组,同时只为每一组返回一行记录,那么所以的记录都将是不相同的。 

    第十一步:应用order by子句。按照order_by_condition排序vt9,此时返回的一个游标,而不是虚拟表。sql是基于集合的理论的,集合不会预先对他的行排序,它只是成员的逻辑集合,成员的顺序是无关紧要的。对表进行排序的查询可以返回一个对象,这个对象包含特定的物理顺序的逻辑组织。这个对象就叫游标。正因为返回值是游标,那么使用order by 子句查询不能应用于表表达式。排序是很需要成本的,除非你必须要排序,否则最好不要指定order by,最后,在这一步中是第一个也是唯一一个可以使用select列表中别名的步骤。 

    第十二步:应用top选项。此时才返回结果给请求者即用户。 

     

    二、mysql的执行顺序 


    1、SELECT语句定义 

    一个完成的SELECT语句包含可选的几个子句。SELECT语句的定义如下: 
    SQL代码 

    <SELECT clause> [<FROM clause>] [<WHERE clause>] [<GROUP BY clause>] [<HAVING clause>] [<ORDER BY clause>] [<LIMIT clause>] 

    SELECT子句是必选的,其它子句如WHERE子句、GROUP BY子句等是可选的。 
    一个SELECT语句中,子句的顺序是固定的。例如GROUP BY子句不会位于WHERE子句的前面。 

    2、SELECT语句执行顺序 

    SELECT语句中子句的执行顺序与SELECT语句中子句的输入顺序是不一样的,所以并不是从SELECT子句开始执行的,而是按照下面的顺序执行: 

    开始->FROM子句->WHERE子句->GROUP BY子句->HAVING子句->ORDER BY子句->SELECT子句->LIMIT子句->最终结果 

    每个子句执行后都会产生一个中间结果,供接下来的子句使用,如果不存在某个子句,就跳过 
    对比了一下,mysql和sql执行顺序基本是一样的, 标准顺序的 SQL 语句为: 

    select 考生姓名, max(总成绩) as max总成绩 
    
    from tb_Grade 
    
    where 考生姓名 is not null 
    
    group by 考生姓名 
    
    having max(总成绩) > 600 
    
    order by max总成绩 


     在上面的示例中 SQL 语句的执行顺序如下: 

       (1). 首先执行 FROM 子句, 从 tb_Grade 表组装数据源的数据 

       (2). 执行 WHERE 子句, 筛选 tb_Grade 表中所有数据不为 NULL 的数据 

       (3). 执行 GROUP BY 子句, 把 tb_Grade 表按 "学生姓名" 列进行分组(注:这一步开始才可以使用select中的别名,他返回的是一个游标,而不是一个表,所以在where中不可以使用select中的别名,而having却可以使用,感谢网友  zyt1369  提出这个问题)
       (4). 计算 max() 聚集函数, 按 "总成绩" 求出总成绩中最大的一些数值 

       (5). 执行 HAVING 子句, 筛选课程的总成绩大于 600 分的. 

       (7). 执行 ORDER BY 子句, 把最后的结果按 "Max 成绩" 进行排序. 

     

    希望此篇文章能让大家对mysql执行顺序有一个了解,另外为大家推荐两篇MySQL优化的文章:

    MySQL优化之推荐使用规范

    MySQL优化之my.conf配置详解

    大家可关注我的微信公众号:裸睡的猪,后期会为大家推荐更多有用的文章!


     

    展开全文
  • 一同学去面试,面试官让说一下sql的执行顺序,他尽然答错了,面试也就到此结束了!实属不应该。。。

    写在前面: 我是「扬帆向海」,这个昵称来源于我的名字以及女朋友的名字。我热爱技术、热爱开源、热爱编程。技术是开源的、知识是共享的

    这博客是对自己学习的一点点总结及记录,如果您对 Java算法 感兴趣,可以关注我的动态,我们一起学习。

    用知识改变命运,让我们的家人过上更好的生活

    昨天一个同学去面试某公司,面试官让他说一下sql的执行顺序,他尽然答错了,面试也就到此结束了!实属不应该。。。

    在这里插入图片描述

    借这个机会,在这里做一下简单的总结!


    1. 书写顺序

    按以下的顺序书写sql语句

    SELECT 查询列表.
    FROM1                                      
    【连接类型】 JOIN2						   
    ON 连接条件
    WHERE 筛选条件
    GROUP BY 分组列表
    HAVING 分组后的筛选条件
    ORDER BY 排序的字段
    LIMIT 起始的条目索引,条目数;
    

    即:

    SELECTFROMJOINONWHEREGROUP BYHAVINGORDER BYLIMIT

    注意

    ① 连接类型有:innerleft outerright outercross

    ② 起始条目索引默认从0开始;

    ③ 若 每页显示条目数:pageSize,要显示的页数:page
    则有:

    SELECT * FROMLIMIT (page-1* pageSize,pageSize
    

    2. 执行顺序

    按右边标出的 ①-⑨ 的顺序执行

    SELECT 查询列表				⑦					
    FROM1					①                                      
    【连接类型】 JOIN2ON 连接条件					②
    WHERE 筛选条件				④
    GROUP BY 分组列表			⑤
    HAVING 分组后的筛选条件		⑥
    ORDER BY 排序的字段			⑧
    LIMIT 起始的条目索引,条目数;

    即:

    FROMONJOINWHEREGROUP BYHAVINGSELECTORDER BYLIMIT


    由于水平有限,本博客难免有不足,恳请各位大佬不吝赐教!

    展开全文
  • 在Java中多个 if-else 之间的执行顺序有什么区别呢? 对于 if-else 语句,它是 单条件双分支语句,即程序的执行流程是根据 一个条件来控制的; 如下代码演示了存在多个 if - else 时的执行顺序: int test11 = ...

    在Java中多个 if-else 之间的执行顺序有什么区别呢?

    对于 if-else 语句,它是 单条件双分支语句,即程序的执行流程是根据 一个条件来控制的;

    如下代码演示了存在多个 if - else 时的执行顺序:

                    int test11 = 2;
    		if (test11 > 1) {    // if语句判断
    			int test21 = 10;
    			test11 = test21;
    			System.out.println(test11); // if表达式的值为true,则输出test1为10
    		}else{
    			int test31 = 100;
    			test11 = test31;
    			System.out.println(test11); // if表达式的值为false,则输出test1为100
    		}
    		if (test11 < 1) {    // if语句判断
    			int test21 = 10;
    			test11 = test21;
    			System.out.println(test11); // if表达式的值为true,则输出test1为10
    		}else{
    			int test31 = 100;
    			test11 = test31;
    			System.out.println(test11); // if表达式的值为false,则输出test1为100
    		}

    一、在代码中,存在两个 if-else 语句 ,程序执行时他们相互之间是独立的,互不干扰的;

    二、这两个 if - else 执行顺序为:

    1、先执行第一个 if - else 语句中的 if ( test11 > 1 ) ,当表达式 test11 > 1 为 true 时,则执行其 { } 里面的若干语句,在这里是执行三条语句;当执行完 { } 中的三条语句后,就结束第一个 if - else 语句了 , else {} 部分是不会再执行了,即:

    else{
                int test31 = 100;
                test11 = test31;
                System.out.println(test11); // if表达式的值为false,则输出test1为100
            }

     是不再执行的;反之,当表达式 test11 > 1 为 false 时 ,则不会执行其 { } 里面的三条语句 ,而是执行 else 后面的 { } 中三条语句 ,执行完三条语句后,就结束第一个 if - else 语句了 ;

    2、当第一个 if - else 结束后,执行顺序就到 第二个 if - else 语句,和第一个 if - else 一样,先判断语句 if (test11 < 1) 中表达式的值,当表达式 test11 < 1 为 true 时,则执行其 { } 里面的若干语句,并结束第二个 if - else 语句 ,否则执行 else 后面的 { } 中的语句,并结束第二个 if - else 语句;

    3、以上代码演示最终输出为:10  100 ;

    4、if - else 总结:对于 if - else 语句 就是 ,先判断表达式的值,为true则执行其 { } 中若干语句,并结束语句,为false则执行其 else 后面的 { }中的语句,并结束语句;

    再次强调:

    对于 多个 if - else 语句,程序执行时是从第一个 if - else 开始判断的,只有当执行完第一个 if - else ,程序才会继续往下执行第二个,第三个,第四个 if - else 语句,而且每个 if - else 语句之间是独立的,互不干扰的,你执行你的 if - else ,我执行我的 if - else ;


    在Java中 if-else 与 if-else if-else之间不同执行顺序:

    一、首先要了解 if - else 与 if - else if - else 之间的本质是不一样的:

    1、if - else 是 单条件双分支 语句; if - else if - else  是 多条件分支 语句 ;

    if - else 单条件双分支 语句是:

    一个条件控制两个分支语句执行顺序,当条件为 true 则执行其对应的一个分支语句,而另外一个分支就不再执行了,当条件为 false 则执行其对应的一个分支语句,而另外一个分支也不会再执行了;

    if - else if - else 多条件分支 语句是:

    • 语句中有多个条件,每一个条件控制自己一个分支语句,语句执行时,先从第一个 if ( ) 中的表达式开始判断,当表达式中值为 true 则执行该 { } 中若干语句,并结束当前整个 if - else if - else ,也就是后面的 else if - else 都不会再继续判断和执行了;
    • 当第一个 if ( ) 中的表达式的值为false时,则往下对 else if 进行判断,一直到多个条件中有表达式的值为true,才结束语句;
    • 若多个条件都为false时,则执行最后 else 后面 { } 中的若干语句,并结束当前整个 if - else if - else ;
    • 如下代码进行演示:
    • 代码中每个 if () 中表达式的值都是 false ,所以最后只执行 else {} 中的若干语句,并结束当前语句,程序输出为 100000 ;
                    int test1 = 10 ;
    		if(test1<1){
    			test1 = 100;
    			System.out.println(test1);  // 当表达式 test<1 为true,则输出 test1 的值为100
    		}else if(test1<2){
    			test1 = 1000;
    			System.out.println(test1);  // 当表达式 test<2 为true,则输出 test1 的值为 1000
    		}else{
    			test1 = 100000;
    			System.out.println(test1);  
    // 当以上表达式都为false时,则输出 test1 的值为 100000,并结束该if-else if-else语句
    		}

    那么 if-else 与 if-else if-else之间不同执行顺序是:

    • 对于 if - else 语句,系统程序只会进行一次表达式的判断,当表达式的值为 true 则执行其 { } 中的若干语句,并结束当前整个语句,后面的 else 不再执行了;若表达式的值为 false 则执行其 else { } 中的若干语句,并结束当前整个语句;
    • 对于 if - else if - else 语句,系统程序会进行多次表达式的判断,直到其中有一个表达式的值为 true ,才会执行其对应的若干语句,并结束当前整个语句;若全部表达式的值都为 false 时,则执行其最后 else { } 中的若干语句,并结束当前整个语句;

    需要注意的是:有多个 else if 语句的情况下,如 if - else if - else if - else if - else :

    要是 if 中表达式为  false ,下面三个 else if 的表达式的值都是 true 那要怎么执行呢?

    其实很简单,当 三个 else if 的表达式的值都是 true 时,系统程序只会执行第一个 else if 中表达式的值为true的若干语句,并结束当前整个语句,而后面两个 else if 是不会被执行的; 如下代码进行演示:

                    int test1 = 10 ;
    		if(test1<1){
    			test1 = 100;
    			System.out.println(test1);  // 当表达式 test<1 为true,则输出 test1 的值为100
    		}else if(test1>2){
    			test1 = 1000;
    			System.out.println(test1);  // 当表达式 test<2 为true,则输出 test1 的值为 1000
    		}else if(test1>3){
    			test1 = 10000;
    			System.out.println(test1);  // 当表达式 test<3 为true,则输出 test1 的值为 10000
    		}else if(test1>4){
    			test1 = 100000;
    			System.out.println(test1);  // 当表达式 test<3 为true,则输出 test1 的值为 100000
    		}else{
    			test1 = 0;
    			System.out.println(0);  // 当以上表达式都为false时,则输出 test1 的值为 0,并结束当前整个语句
    		}

    在代码中,test1 > 2 , test1 > 3 , test1 > 4 都是为true的,但是程序只会执行第一个表达式 test1 > 2 的若干语句,并结束整个语句了,后面的 test1 > 3 , test1 > 4 都不会在判断和执行了;


    以下单独对 if 语句、if else语句、if - else if - else 语句、switch开关语句进行逐一分析:

    一、if语句是单条件单分支语句,根据一个条件来控制程序执行的流程;

    1、if语句的语法格式:

    if(表达式){
      若干语句
    }

    2、if语句中表达式的值必须是boolean类型的,当值为 true 时,则执行 {} 中的 若干语句 ;当值为 false 时则结束当前 if 语句;

    以下代码进行演示: 表达式 test>1 为真,所以执行 {} 中的三条语句,最后结果输出 100 ;

                    int test = 10 ;
    		if(test>1){                  //if语句判断
    			int tests = 100 ; 
    			test = tests ;
    			System.out.println(test);    //输出test为100
    		}

    3、if语句中,当 {} 中的语句只有一条时,可以省略 {} , 但是为了增强代码的可读性,建议大家不要省略;如下演示:

            int test = 10 , tests = 100 ;                
            if(test>1){
    	   System.out.println(test);  // test>1为真,输出test
    	}
            if(tests<1)
               tests = test ;
    	System.out.println(tests); // tests<1为假,则不进行tests = test ;语句,输出tests为100

    二、if-else语句是单条件双分支语句,与if语句一样根据一个条件来控制程序执行的流程;

    1、if-else语句的语法格式:

    if(表达式){
      若干语句
    }else{
      若干语句
    }

    2、if-else语句中表达式的值必须是boolean类型的,当值为 true 时,则执行紧跟 () 后面的 {} 中的若干语句 ;当值为 false 时则执行紧跟 关键字else 后面的 {} 中的若干语句 ;

    以下代码进行演示: 表达式 test > 1 为真,所以执行紧跟 () 后面的 {} 中的语句,最后结果输出 10 ;

                    int test1 = 2;
    		if (test1 > 1) {    // if语句判断
    			int test2 = 10;
    			test1 = test2;
    			System.out.println(test1); // if表达式的值为true,则输出test1为10
    		}else{
    			int test3 = 100;
    			test1 = test3;
    			System.out.println(test1); // if表达式的值为false,则输出test1为100
    		} 

    3、if-else语句中,当 {} 中的语句只有一条时,可以省略 {} , 但是为了增强代码的可读性,建议大家不要省略;如下演示:

            int test1 = 2;
    	if (test1 > 1)     // if语句判断
    	    test1 = 10;    // if表达式的值为true,则输出test1为10
    	else
    	    test1 = 100;   // if表达式的值为false,则输出test1为100
    	System.out.println(test1); // 此输出语句,不属于上面的 if-else 语句当中 ; 用于输出test1的值

    特别注意:以下代码是错误的,报错:Syntax error on token "else", delete this token

            int test1 = 2;
    	if (test1 > 1)     // if语句判断
    	    test1 = 10;
    	    System.out.println(test1); // if表达式的值为true,则输出test1为10
    	else
    	    test1 = 100;
    	    System.out.println(test1); // 此输出语句,不属于上面的 if-else 语句当中 ; 用于输出test1的值

    因为:该 if-else 语句中,紧跟 () 后面的语句已经不止一条了,所以程序报错,对于else后面的 方法调用语句 System.out.println(test1) ;  是不属于该 if-else 语句中的,程序通过;

    解决:去掉 test1 = 10 ; 或者 方法调用语句 System.out.println(test1) ;  即可

    三、if - else if - else 语句是多条件分支语句,即多个条件来控制程序执行的流程;

    1、if - else if - else 语句的语法格式:

    if(表达式){
      若干语句
    }else if(表达式){
      若干语句
    }else if(表达式){
      若干语句
    }
    .
    .
    .
    else{
      若干语句
    }
    
    

    2、if - else if - else 语句中每个 if 后面中表达式的值必须是boolean类型的,当值为 true 时,则执行紧跟该if的 () 后面的 {} 中的若干语句 ;当值为 false 时则继续判断下一个 else if 的 () 中表达式的值,以此类推,直到结束该  if - else if - else 语句 ;

    以下代码进行演示: 当每个if后面的表达式都为 false 时,则执行最后 else 中的若干语句,最后输出test1为 100000 ;

                    int test1 = 10 ;
    		if(test1<1){
    			test1 = 100;
    			System.out.println(test1);  // 当表达式 test<1 为true,则输出 test1 的值为 100
    		}else if(test1<2){
    			test1 = 1000;
    			System.out.println(test1);  // 当表达式 test<2 为true,则输出 test1 的值为 1000
    		}else if(test1<3){
    			test1 = 10000;
    			System.out.println(test1);  // 当表达式 test<3 为true,则输出 test1 的值为 10000
    		}else{
    			test1 = 100000;
    			System.out.println(test1);  
    // 当以上表达式都为false时,则输出 test1 的值为 100000,并结束该if-else if-else语句
    		}

    3、if - else if - else 语句中,当每个 if 后面 {} 中的语句只有一条时,可以省略 {} , 但是为了增强代码的可读性,建议大家不要省略;和以上 if 语句、if - else 语句 是一样的;

    4、需要注意的是,对于 if - else if - else 语句中没有最后的 else 且 每个if 后面的表达式都为 false 时,则结束当前的 if - else if - else 语句;

    、switch 开关语句是单条件多分支语句;

    1、switch 语句的语法格式:其中 break 是可选的,用于结束当前 switch 开关语句;

    switch(表达式){
      case 常量值1: 若干语句 break;
      case 常量值2: 若干语句 break;
      case 常量值3: 若干语句 break;
      ...
      case 常量值n: 若干语句 break;
      default:
             若干语句
    }

    2、switch 语句的执行流程:

    • switch首先判断表达式的值,要是表达式中的值 与 case 后面的常量值相等,就执行该 case 里的若干语句直到遇见break语句为止;
    • 若执行该 case 里的若干语句没有break语句时,则程序不止执行该 case 里的若干语句,还会继续执行后继的 case 里的若干语句,直到遇见 break 语句 ;
    • 若 switch 语句中 表达式的值 与 属于 case 后面的常量值都不相等,则执行 default 后面的若干语句 ;其中 default 是可以不要的;
    • 若 switch 语句中 表达式的值 与 属于 case 后面的常量值都不相等,并且没有 default 时,该 switch 语句不执行任何操作;
    • 如下演示:因为 case 1: 后面没有 break 语句,所以会继续执行后继的 case 里的若干语句,直到遇见break语句,结果输出为 1 2 11 ;
                    int test = 1 ;
    		switch(test){
    		 case 1: test = 1 ;System.out.println(test); 
    		 case 2: test = 2 ;System.out.println(test); 
    		 case 11: test = 11 ;System.out.println(test); break;
                     case 12: test = 12 ;System.out.println(test); 
    		 default: test = 0 ;
    		}

    3、switch 语句中 () 里 “ 表达式 ” 的值可以是byte、short、int、char类型的值;如下演示:

                    int test = 11 ;
    		double testd = 100 ;
    		switch(test){
    		 case 1: test = 1 ;System.out.println(test); break; 
    		 case 2: test = 2 ;System.out.println(test); break; 
    		 case 11: test = 11 ;System.out.println(test); break; 
    		 default: test = 0 ;
    		}

    需要注意的是,switch 中 () 里 “ 表达式 ” 的值不可以是 long、float、double 类型的值,否则报错:

    Cannot switch on a value of type double. Only convertible int values, strings or enum variables are permitted

    4、switch 语句中 case 常量值: 中常量值也可以是byte、short、int、char类型的值,而且是互不相同的;如下演示:

                    int test = 1 ;
    		switch(test){
    		 case 1: test = 1 ;System.out.println(test); 
    		 case 2: test = 2 ;System.out.println(test); 
    		 case 'a': test = 11 ;System.out.println(test); break; 
    		 case (byte)10: test = 12 ;System.out.println(test); 
    		 default: test = 0 ;
    		}

    总结 if、if-else、if-else if-else语句 与 switch 开关语句 之间的异同点:

    1、if、if-else、if- else if- else 语句 之间的共同点是程序根据 一个条件执行一个分支操作,而不是选择执行多个分支操作;

    2、与上面 if、if-else、if- else if- else 语句 不同的是, 在switch语句中,可以通过合理地使用 break 语句,达到一个条件执行一个分支的操作(即只执行一个case后面的若干语句),也可以达到多个操作的操作(即执行多个case后面的若干语句,如以上第2点的代码演示);

    代码练习: 使用switch语句实现 判断用户从键盘输入一个整数是否为中奖号码;

          System.out.println("请输入一个整数进行抽奖,并按回车键(Enter)结束输入:");
    		Scanner inputs = new Scanner(System.in);
    		int number = inputs.nextInt();
    		switch(number){
    		 case 11: System.out.println("恭喜中特等奖!中奖号码为:"+number);break;
    		 case 12: 
    		 case 13: System.out.println("恭喜中一等奖!中奖号码为:"+number);break;
    		 case 14:
    		 case 15:
    		 case 19: System.out.println("恭喜中二等奖!中奖号码为:"+number);break;
    		 case 22:
                     case 23:
                     case 24:
    		 case 25: System.out.println("恭喜中三等奖!中奖号码为:"+number);break;
    		 default: System.out.println("很遗憾"+number+"没有中奖");
    		}

    其中:特等奖为一名,一等奖为两名,二等奖为三名,三等奖为四名;

     

     

     

    展开全文
  • MySql执行顺序及执行计划

    万次阅读 多人点赞 2019-03-06 12:41:12
    一、mySql的执行顺序 mysql执行sql的顺序从 From 开始,以下是执行的顺序流程 1、FROM table1 left join table2 on 将table1和table2中的数据产生笛卡尔积,生成Temp1 2、JOINtable2 所以先是确定表,再确定关联...
  • For循环执行顺序流程

    万次阅读 多人点赞 2018-05-07 15:06:15
    有以下for循环执行代码较为基础,所以画图给大家讲解一下for循环执行步骤1.执行for循环体里的第一个参数,也就是定义一个int整形变量,其变量名为i,并初始化为02.执行完第一个参数里的代码后,会执行第二个参数,...
  • junit 测试执行顺序 一般实践认为,自动化测试应能够独立运行且无特定顺序,并且测试结果不应依赖于先前测试的结果。 但是在某些情况下,可以证明特定的测试执行顺序是正确的,尤其是在集成或端到端测试中。 默认...
  • 【数据库SQL系列】sql语句执行顺序,你理解了吗

    万次阅读 多人点赞 2020-01-13 15:29:00
    记得前几年,还是初级的时候,面试官问到,请你讲一下sql语句的执行顺序。当时我以为就是按照sql的关键字排列顺序来执行的。当时说完,面试官心里估计已经直接pass我了吧。今天复习的时候,突然想起这个基础知识点,...
  • sql语句执行顺序

    万次阅读 多人点赞 2019-06-23 09:18:23
    sql语句定义和执行顺序 摘自《MySQL技术内幕:SQL编程》 sql语句定义的顺序 (1) SELECT (2)DISTINCT<select_list> (3) FROM <left_table> (4) <join_type> JOIN <right_table> (5) ON <...
  • mysql 执行顺序 SQL语句执行顺序分析

    千次阅读 2013-04-06 18:58:40
    mysql 执行顺序 SQL语句执行顺序分析 (2011-08-30 11:25:02) 转载▼ 标签: 杂谈 分类: 数据库  首先,SELECT语句的基本语法如下:   SELECT selection_lis
  • java代码执行顺序详解

    千次阅读 多人点赞 2019-07-15 11:15:19
    今天我们来聊一聊Java的基础:类中方法的执行顺序。 首先直接给出类代码的执行顺序 但是我们必须要注意的是: 静态代码块只执行一次,也就是说你不管创建的多少对象,静态代码只执行一次。 这是为什么啦? ...
  • try-catch-finally的执行顺序

    万次阅读 多人点赞 2019-03-26 17:03:54
    结论: 不管有没有出现异常,finally代码块都会执行; 不管try和catch的代码块中有return时,finally仍会...分有return和没有return来讨论try-catch-finally执行顺序的情况: 1 无return 举个例子: try { t(); ...
  • Java中while与do-while执行顺序的区别: 一、while 和 do-while都是循环语句,他们的区别是 do-while语句的循环体至少被执行一次,而while语句不用; 如下代码进行演示: int x = 1 ; while(x == 10){ x++; ...
  • MySQL SELECT执行顺序

    千次阅读 2017-08-16 15:36:01
    mysql select 执行顺序, select语句执行顺序, select 执行顺序, sql select执行顺序, mysql语句执行顺序 1、FORM: 对FROM左边的表和右边的表计算笛卡尔积,产生虚表VT1。 2、ON: 对虚表VT1进行ON过滤,只有那些符合...
  • sql语句的执行顺序

    万次阅读 多人点赞 2017-01-10 11:09:04
    理解sql语句的执行顺序对优化sql非常重要,那么sql语句的执行顺序是怎样的呢,以一条简单的的语句做分析:  这一条语句包含我们经常用到的一些关键字,select,from,where,group by,order by,它的执行顺序如下...
  • vue 执行顺序

    万次阅读 2018-08-15 11:05:12
    vue 执行顺序
  • 一、单独讨论javascript的执行顺序1 只有原生的javascript,没有jquery。 1.1在&lt;head&gt;里面的JS谁写在前面,谁就优先执行。 1.2在&lt;body&gt;里面的JS要比&lt;head&gt;里面的JS后...
  • python 代码执行顺序

    万次阅读 多人点赞 2019-05-02 20:22:39
    py文件单独执行时, 按照自上而下的顺序: 首先执行没有缩进的代码,但是`类`中的代码和`函数`中的代码不会执行 (除非被调用)
  • junit测试方法执行顺序

    千次阅读 2017-07-17 16:55:37
    junit测试方法执行顺序Junit 4.11里增加了指定测试方法执行顺序的特性:测试类的执行顺序可通过对测试类添加注解 “@FixMethodOrder(value)” 来指定,其中value 为执行顺序;三种执行顺序可供选择: - 默认...
  • hive语句的书写顺序及执行顺序

    千次阅读 2019-06-10 19:48:44
    1、hive语句的书写顺序:(从前往后) (1)select (2)from (3)join on (4) where (5)group by (6)having (7)distribute by/cluster by (8) sort by (9) order by (10) limit ...2、hive语句的执行顺序:...
  • SQL执行顺序

    千次阅读 2018-08-27 08:15:44
    这是一个很简单的示例,是关于SQL语句执行顺序的。这里将一个普通的SELECT语句,拆分为三个子句。那么在实际的执行过程中,是按照什么顺序处理的呢?这里有A-F六个选项,大家可以思考选择一下… 最终的答案是D,即...
  • @PostConstruct执行顺序

    万次阅读 2019-08-13 12:57:50
    最近看到@PostConstruct这个注解,思考一个问题,这个注释是修饰初始化之后需要执行的方法,那么@PostConstruct和@Autowired、构造函数的执行顺序是什么呢? 写了段代码验证一下 @Service public class BeanA { ...
  • promise执行顺序总结

    千次阅读 2018-11-17 11:11:43
    面试遇到的promise的执行顺序问题,在这里,总结下。之前博客的账号忘记了,新建了一个。 1、 const promise = new Promise((resolve, reject)=&gt;{ console.log(1); resolve(); console.log(2); })...
  • having子句详解&执行顺序

    千次阅读 2017-11-07 11:09:31
    having子句详解&执行顺序
  • @order 通知执行顺序

    千次阅读 2018-05-24 20:30:07
    Spring通知执行顺序 @order注解 Spring 4.2 利用@Order控制配置类的加载顺序 无异常情况 所有通知order一样,执行顺序:around start -&amp;gt; before -&amp;gt;around start -&amp;gt; ...
  • junit执行顺序

    千次阅读 2015-04-16 11:41:33
    Junit 4.11里增加了指定测试方法执行顺序的特性 测试类的执行顺序可通过对测试类添加注解 “@FixMethodOrder(value)” 来指定,其中value 为执行顺序 三种执行顺序可供选择:默认(MethodSorters.DEFAULT),按...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,834,904
精华内容 733,961
关键字:

执行顺序