• 一个例子教你理解java回调机制


    网上很多例子都写的很难理解,笔者刚开始都已经弄晕菜了。

    这个例子,应该是再简单,再简洁不过的了,例子目的是测试某个方法的执行时间。这里就写三个java类,一个接口,一个实现,还有一个用于测试时间的类。

    要测试的方法,尽量占用执行的时间,这样明显一些,这里测试循环1000000次,并且打印出来。

    测试类:

    public class MyMethod {
    
        public void mytest() {
            // TODO Auto-generated method stub
            for (int i = 0; i < 1000000; i++) {
                System.out.println("num:"+i);
            }
        }
    }

    接口CallBack:

    public interface CallBack {
        void execute();
    }

    实现类:

    public class TestTime {
        public void testTime(CallBack callBack){
            long begin=System.currentTimeMillis();
            System.out.println("begin time:"+begin);
            callBack.execute();
            long end=System.currentTimeMillis();
            System.out.println("end time:"+end);
            System.out.println("use time:"+(end-begin));
        }
        /**
         * @param args
         */
        public static void main(String[] args) {
            // TODO Auto-generated method stub
            TestTime TT=new TestTime();
            TT.testTime(new CallBack() {            
                @Override
                public void execute() {
                    // TODO Auto-generated method stub
                    (new MyMethod()).mytest(); //执行测试方法
                }
            });
    }
    }

    控制台会输出:

    ......

    num:999998
    num:999999
    end time:1403838433171
    use time:8093

    好了,这就实现回调了。

    刚接触这个的,会觉得,这就是实现回调了?

    笔者对回调的大致理解是:A调用了B,执行后,B又调用A。上面的实现类是写在了一起。主类(A)的main方法调用了主类中的testTime方法(这个testTime可以单独写到一个类(B)中,就相当于B类中的方法,只不过这里写到了一起),所以可以简单理解为A调用了B。然后B又调用了A中的测试方法MyMethod.mytest()方法(消耗了很久时间,并且B自己计算了时间)。

    这样,大概就理解了吧。

    使用回调有什么好处呢?

    好处大概就是只关心自己的业务,不用在乎其它的东西。就像上面,计算方法执行时间的类,只需要调用一下它就好了,不用去管他是如何来执行,如何来实现那个计算方法的。如果用过jdbcTemplate的话,应该更容易理解一些。jdbctemplate也是使用回调的,用户只需要关心对自己对象的操作,而不用关心其他的,比如连接数据库,执行sql语句等问题。

    推而广之,我们大概可以写一个jdbctemplate的简单模型,比如数据库的更新插入操作。

    Callback的接口:

    import com.mysql.jdbc.PreparedStatement;
    
    public interface PreparedStatementSetter {
        public void setValues(PreparedStatement ps);
    }

    更新的方法:

    import com.mysql.jdbc.PreparedStatement;
    
    public class JdbcTemplate {
        public void update(String sql,PreparedStatementSetter pss) throws SQLException{
            PreparedStatement preparedStatement=null;
            preparedStatement.execute(sql);
        }
    }

    我们自己的方法去实现:

    import java.sql.SQLException;
    
    import com.mysql.jdbc.PreparedStatement;
    
    public class Main {
        public Main() throws SQLException {
            // TODO Auto-generated constructor stub
            JdbcTemplate jdbcTemplate=new JdbcTemplate();
            String sql="insert into table values(?,?)";
            jdbcTemplate.update(sql, (new PreparedStatementSetter() {
                
                @Override
                public void setValues(PreparedStatement ps) {
                    // TODO Auto-generated method stub
                    
                }
            }));
        }
    }

    这和jdbctemplate是不是非常像,大概就是这么些。希望有助于很多像我一样对回调迷茫了很久的人。

  • 相关阅读:
    virtualenv
    linux基础命令:
    middleware
    scrapy-redis
    kubernetes 应用快速入门
    linux expect spawn的用法
    Linux 内存分析工具—free命令
    kubeadm安装kubenetes1.15.4集群
    kubenetes基本概念和术语
    docker-machine使用
  • 原文地址:https://www.cnblogs.com/juepei/p/3811801.html
Copyright © 2020-2023  润新知