JAVA面试,try、catch、finally带return的执行顺序总结Demo案例

在进行本文demo案例测试之前,可以先看看这篇文章: 详解Throwable类,精心制作. ,了解、学习一下理论基础。

在日常求职面试中,我不仅一次遇到 try-catch-finally 中带有 return ,之后需要给出他们的返回值。这次观看同行小伙伴的文章,之后自己编写了一些Demo案例,理解的更加深刻了。

感谢小伙伴的分享。在他分享的文章中,我找到了Demo案例中的一点小问题,并给出了评论,大家可以仔细观看。

以下是我的Demo案例,各位小伙伴可以直接复制、粘贴到 IDEA 中,自己测试、运行一下看看。

package com.moon.learning.exception;

import com.alibaba.fastjson2.JSON;

import java.util.ArrayList;
import java.util.List;

public class ExceptionTest01 {

    public static void main(String[] args) {

//        System.out.println("---------------- 异常类测试 ----------------");
//        testException();


//        System.out.println("---------------- 异常类测试2 ----------------");
//        testException2();


//        System.out.println("---------------- 测试多异常类信息 ----------------");
//        testManyException();

//        System.out.println("(1 + 3) 测试:" + (1 + 3));


        System.out.println("---------------- try-catch-finally 中,try代码块中 return 返回 int类型数据. ----------------");
        int i = testReturnInt();
        System.out.println("方法体外,i值为:" + i);  // 返回值:方法体外,i值为:3

        System.out.println("---------------- try-catch-finally 中测试 return 返回 List类型数据. ----------------");
        List<Integer> list = testReturnList();
        System.out.println("方法体外,list值为:" + JSON.toJSONString(list));  // 返回值:方法体外,list值为:[1,3]

        System.out.println("---------------- try-catch-finally 中,catch代码块中 return 返回 int类型数据. ----------------");
        int i2 = testReturnInt2();
        System.out.println("方法体外,i2值为:" + i2);  // 返回值:方法体外,i2值为:4

        System.out.println("---------------- try-catch-finally 中,finally代码块中 return 返回 int类型数据. ----------------");
        int i3 = testReturnInt3();
        System.out.println("方法体外,i3值为:" + i3);  // 返回值:方法体外,i3值为:4
        
        
    }


    /**
     * 测试异常类
     *
     */
    public static void testException() {

        Exception exception = new Exception("Exception异常...");
        Error error = new Error("Error异常...");
        Throwable throwable = new Throwable("Throwable异常...");

        System.out.println("exception为:" + JSON.toJSONString(exception));
        System.out.println("error为:" + JSON.toJSONString(error));
        System.out.println("throwable为:" + JSON.toJSONString(throwable));
    }


    /**
     * 测试异常类2
     */
    public static void testException2() {

        try {

            System.out.println("begin...");
            System.out.println("10/0 = " + (10 / 0));
            System.out.println("try end,看看会不会走到这行代码...");
        } catch (Exception e) {
            System.out.println("message为:" + JSON.toJSONString(e.getMessage()));
            System.out.println("e为:" + JSON.toJSONString(e));
//            e.printStackTrace();  // 如果开启这行代码,关闭 throw e, 则 下行中的 (2 + 5) 会正常运行、(1 + 3) 会正常运行.
            throw e;  // 若开启这行代码,下行中的  (2 + 5) 不会运行、(1 + 3) 不会运行.
        }

        System.out.println("是否走到这里~~~:" + (2 + 5));
    }


    /**
     * 测试多异常类信息
     */
    public static void testManyException() {

        try {

            System.out.println("begin...");
//            int num = Integer.valueOf("abc");  // 异常1
            int num = Integer.valueOf("5");  // 异常1
            System.out.println("num值为:" + num);

            System.out.println("10/0 = " + (10 / 0));  // 异常2
            System.out.println("try end ...");
        } catch (ClassCastException e) {

            System.out.println("ClassCastException 中 Message为:" + JSON.toJSONString(e.getMessage()));
            System.out.println("ClassCastException为:" + JSON.toJSONString(e));
            e.printStackTrace();
            throw e;
        } catch (ArithmeticException e) {

            System.out.println("ArithmeticException 中 Message为:" + JSON.toJSONString(e.getMessage()));
            System.out.println("ArithmeticException为:" + JSON.toJSONString(e));
            e.printStackTrace();
            throw e;
        } catch (Exception e) {

            System.out.println("Exception 中 Message为:" + JSON.toJSONString(e.getMessage()));
            System.out.println("Exception为:" + JSON.toJSONString(e));
            e.printStackTrace();
            throw e;
        } finally {

            System.out.println("走到 finally 中了,end...");
        }

        System.out.println("(3+ 6)测试:" + (3+ 6));
    }


    /**
     * 测试:try-catch-finally 中,try代码块中 return 返回 int类型数据.
     */
    public static int testReturnInt() {

        int i = 2;

        try {
            i++;
            System.out.println("try中i为:" + i);
            return i;
        } catch (Exception e) {
            i++;
            System.out.println("catch中i为:" + i);
//            System.out.println("Exception为:" + JSON.toJSONString(e));
            e.printStackTrace();
            throw e;
        } finally {

            i++;
            System.out.println("finally中,i值为:" + i);
        }

//        System.out.println("try-catch-finally方法块外,i值为:" + i);
//        return i;
    }


    /**
     * 测试:try-catch-finally 中,try代码块中 return 返回 List类型数据.
     *
     * @return
     */
    public static List<Integer> testReturnList() {

        List<Integer> list = new ArrayList<>();

        try {

            list.add(1);
            System.out.println("try 中list为:" + JSON.toJSONString(list));
            return list;
        } catch (Exception e) {
            list.add(2);
            e.printStackTrace();
            System.out.println("catch 中list为:" + JSON.toJSONString(list));
            throw e;
        } finally {

            list.add(3);
            System.out.println("finally 中list为:" + JSON.toJSONString(list));
        }

//        return list;
    }


    /**
     * 测试:try-catch-finally 中,catch代码块中 return 返回 int类型数据.
     */
    public static int testReturnInt2() {

        int i = 2;

        try {

            i++;
            System.out.println("try 中i为:" + i);
            int x = i / 0;
        } catch (Exception e) {

            i++;
            System.out.println("catch 中i为:" + i);
            e.printStackTrace();
            return i;
//            throw e;  // 写这行代码,会引起编译报错。
        } finally {

            i++;
            System.out.println("finally 中i为:" + i);
        }

        return i;
    }


    /**
     * 测试:try-catch-finally 中,finally代码块中 return 返回 int类型数据.
     */
    public static int testReturnInt3() {

        int i = 2;

        try {

            i++;
            System.out.println("try 中i为:" + i);
//            int x = i / 0;  // 这行代码,可以取消、添加上测试,看看 i 的值.
            return i;
        } catch (Exception e) {
            i++;
            System.out.println("catch 中i为:" + i);
            e.printStackTrace();
            return i;
//            throw e;  // 写这行代码,会引起编译报错。
        } finally {

            i++;
            System.out.println("finally 中i为:" + i);
            return i;
        }

//        return i;
    }
    
    
}

运行上面的代码,返回的log日志如下所示,可以自己看看log日志。

"D:\Program Files\Java\jdk1.8.0_25\bin\java.exe" "-javaagent:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\lib\idea_rt.jar=49279:D:\Program Files\JetBrains\IntelliJ IDEA 2019.3.5\bin" -Dfile.encoding=UTF-8 -classpath "D:\Program Files\Java\jdk1.8.0_25\jre\lib\charsets.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\deploy.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\access-bridge-64.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\cldrdata.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\dnsns.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jaccess.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\jfxrt.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\localedata.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\nashorn.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunec.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunjce_provider.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunmscapi.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\sunpkcs11.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\ext\zipfs.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\javaws.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\jce.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\jfr.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\jfxswt.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\jsse.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\management-agent.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\plugin.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\resources.jar;D:\Program Files\Java\jdk1.8.0_25\jre\lib\rt.jar;D:\Coding_myself\Project-IDEA\Project-01\demo-01\target\classes;D:\Maven\maven_repository\org\mybatis\spring\boot\mybatis-spring-boot-starter\1.3.2\mybatis-spring-boot-starter-1.3.2.jar;D:\Maven\maven_repository\org\springframework\boot\spring-boot-starter\1.5.10.RELEASE\spring-boot-starter-1.5.10.RELEASE.jar;D:\Maven\maven_repository\org\springframework\boot\spring-boot\1.5.10.RELEASE\spring-boot-1.5.10.RELEASE.jar;D:\Maven\maven_repository\org\springframework\boot\spring-boot-autoconfigure\1.5.10.RELEASE\spring-boot-autoconfigure-1.5.10.RELEASE.jar;D:\Maven\maven_repository\org\springframework\boot\spring-boot-starter-logging\1.5.10.RELEASE\spring-boot-starter-logging-1.5.10.RELEASE.jar;D:\Maven\maven_repository\ch\qos\logback\logback-classic\1.1.11\logback-classic-1.1.11.jar;D:\Maven\maven_repository\ch\qos\logback\logback-core\1.1.11\logback-core-1.1.11.jar;D:\Maven\maven_repository\org\slf4j\jcl-over-slf4j\1.7.25\jcl-over-slf4j-1.7.25.jar;D:\Maven\maven_repository\org\slf4j\jul-to-slf4j\1.7.25\jul-to-slf4j-1.7.25.jar;D:\Maven\maven_repository\org\slf4j\log4j-over-slf4j\1.7.25\log4j-over-slf4j-1.7.25.jar;D:\Maven\maven_repository\org\springframework\spring-core\4.3.14.RELEASE\spring-core-4.3.14.RELEASE.jar;D:\Maven\maven_repository\org\yaml\snakeyaml\1.17\snakeyaml-1.17.jar;D:\Maven\maven_repository\org\springframework\boot\spring-boot-starter-jdbc\1.5.10.RELEASE\spring-boot-starter-jdbc-1.5.10.RELEASE.jar;D:\Maven\maven_repository\org\apache\tomcat\tomcat-jdbc\8.5.27\tomcat-jdbc-8.5.27.jar;D:\Maven\maven_repository\org\apache\tomcat\tomcat-juli\8.5.27\tomcat-juli-8.5.27.jar;D:\Maven\maven_repository\org\springframework\spring-jdbc\4.3.14.RELEASE\spring-jdbc-4.3.14.RELEASE.jar;D:\Maven\maven_repository\org\springframework\spring-tx\4.3.14.RELEASE\spring-tx-4.3.14.RELEASE.jar;D:\Maven\maven_repository\org\mybatis\spring\boot\mybatis-spring-boot-autoconfigure\1.3.2\mybatis-spring-boot-autoconfigure-1.3.2.jar;D:\Maven\maven_repository\org\mybatis\mybatis\3.4.6\mybatis-3.4.6.jar;D:\Maven\maven_repository\org\mybatis\mybatis-spring\1.3.2\mybatis-spring-1.3.2.jar;D:\Maven\maven_repository\cn\hutool\hutool-all\4.5.11\hutool-all-4.5.11.jar;D:\Maven\maven_repository\io\springfox\springfox-swagger2\2.6.1\springfox-swagger2-2.6.1.jar;D:\Maven\maven_repository\io\swagger\swagger-annotations\1.5.10\swagger-annotations-1.5.10.jar;D:\Maven\maven_repository\io\swagger\swagger-models\1.5.10\swagger-models-1.5.10.jar;D:\Maven\maven_repository\com\fasterxml\jackson\core\jackson-annotations\2.4.5\jackson-annotations-2.4.5.jar;D:\Maven\maven_repository\io\springfox\springfox-spi\2.6.1\springfox-spi-2.6.1.jar;D:\Maven\maven_repository\io\springfox\springfox-core\2.6.1\springfox-core-2.6.1.jar;D:\Maven\maven_repository\io\springfox\springfox-schema\2.6.1\springfox-schema-2.6.1.jar;D:\Maven\maven_repository\io\springfox\springfox-swagger-common\2.6.1\springfox-swagger-common-2.6.1.jar;D:\Maven\maven_repository\io\springfox\springfox-spring-web\2.6.1\springfox-spring-web-2.6.1.jar;D:\Maven\maven_repository\com\google\guava\guava\18.0\guava-18.0.jar;D:\Maven\maven_repository\com\fasterxml\classmate\1.3.1\classmate-1.3.1.jar;D:\Maven\maven_repository\org\slf4j\slf4j-api\1.7.21\slf4j-api-1.7.21.jar;D:\Maven\maven_repository\org\springframework\plugin\spring-plugin-core\1.2.0.RELEASE\spring-plugin-core-1.2.0.RELEASE.jar;D:\Maven\maven_repository\org\springframework\spring-beans\4.0.9.RELEASE\spring-beans-4.0.9.RELEASE.jar;D:\Maven\maven_repository\org\springframework\spring-context\4.0.9.RELEASE\spring-context-4.0.9.RELEASE.jar;D:\Maven\maven_repository\org\springframework\spring-expression\4.0.9.RELEASE\spring-expression-4.0.9.RELEASE.jar;D:\Maven\maven_repository\org\springframework\spring-aop\4.0.9.RELEASE\spring-aop-4.0.9.RELEASE.jar;D:\Maven\maven_repository\aopalliance\aopalliance\1.0\aopalliance-1.0.jar;D:\Maven\maven_repository\org\springframework\plugin\spring-plugin-metadata\1.2.0.RELEASE\spring-plugin-metadata-1.2.0.RELEASE.jar;D:\Maven\maven_repository\org\mapstruct\mapstruct\1.0.0.Final\mapstruct-1.0.0.Final.jar;D:\Maven\maven_repository\com\spring4all\swagger-spring-boot-starter\1.9.0.RELEASE\swagger-spring-boot-starter-1.9.0.RELEASE.jar;D:\Maven\maven_repository\io\springfox\springfox-swagger-ui\2.9.2\springfox-swagger-ui-2.9.2.jar;D:\Maven\maven_repository\io\springfox\springfox-bean-validators\2.9.2\springfox-bean-validators-2.9.2.jar;D:\Maven\maven_repository\commons-logging\commons-logging\1.2\commons-logging-1.2.jar;D:\Maven\maven_repository\com\alibaba\fastjson2\fastjson2\2.0.20\fastjson2-2.0.20.jar;D:\Maven\maven_repository\org\apache\commons\commons-lang3\3.6\commons-lang3-3.6.jar;D:\Maven\maven_repository\commons-io\commons-io\2.6\commons-io-2.6.jar;D:\Maven\maven_repository\commons-fileupload\commons-fileupload\1.4\commons-fileupload-1.4.jar;D:\Maven\maven_repository\commons-collections\commons-collections\3.2.2\commons-collections-3.2.2.jar;D:\Maven\maven_repository\com\alibaba\easyexcel\3.1.1\easyexcel-3.1.1.jar;D:\Maven\maven_repository\com\alibaba\easyexcel-core\3.1.1\easyexcel-core-3.1.1.jar;D:\Maven\maven_repository\com\alibaba\easyexcel-support\3.1.1\easyexcel-support-3.1.1.jar;D:\Maven\maven_repository\org\apache\poi\poi\4.1.2\poi-4.1.2.jar;D:\Maven\maven_repository\commons-codec\commons-codec\1.13\commons-codec-1.13.jar;D:\Maven\maven_repository\org\apache\commons\commons-collections4\4.4\commons-collections4-4.4.jar;D:\Maven\maven_repository\org\apache\commons\commons-math3\3.6.1\commons-math3-3.6.1.jar;D:\Maven\maven_repository\com\zaxxer\SparseBitSet\1.2\SparseBitSet-1.2.jar;D:\Maven\maven_repository\org\apache\poi\poi-ooxml\4.1.2\poi-ooxml-4.1.2.jar;D:\Maven\maven_repository\org\apache\commons\commons-compress\1.19\commons-compress-1.19.jar;D:\Maven\maven_repository\com\github\virtuald\curvesapi\1.06\curvesapi-1.06.jar;D:\Maven\maven_repository\org\apache\poi\poi-ooxml-schemas\4.1.2\poi-ooxml-schemas-4.1.2.jar;D:\Maven\maven_repository\org\apache\xmlbeans\xmlbeans\3.1.0\xmlbeans-3.1.0.jar;D:\Maven\maven_repository\org\apache\commons\commons-csv\1.8\commons-csv-1.8.jar;D:\Maven\maven_repository\org\ehcache\ehcache\3.9.9\ehcache-3.9.9.jar;D:\Maven\maven_repository\org\projectlombok\lombok\1.18.20\lombok-1.18.20.jar" com.moon.learning.exception.ExceptionTest01
---------------- try-catch-finally 中,try代码块中 return 返回 int类型数据. ----------------
try中i为:3
finally中,i值为:4
方法体外,i值为:3
---------------- try-catch-finally 中测试 return 返回 List类型数据. ----------------
try 中list为:[1]
finally 中list为:[1,3]
方法体外,list值为:[1,3]
---------------- try-catch-finally 中,catch代码块中 return 返回 int类型数据. ----------------
try 中i为:3
catch 中i为:4
finally 中i为:5
方法体外,i2值为:4
---------------- try-catch-finally 中,finally代码块中 return 返回 int类型数据. ----------------
try 中i为:3
finally 中i为:4
方法体外,i3值为:4
java.lang.ArithmeticException: / by zero
    at com.moon.learning.exception.ExceptionTest01.testReturnInt2(ExceptionTest01.java:194)
    at com.moon.learning.exception.ExceptionTest01.main(ExceptionTest01.java:35)

Process finished with exit code 0


感恩相遇,祝各位小伙伴2023年新年快乐。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 以下是一个简单的Java代码示例,该代码使用Redis实现分布式锁: ```java import redis.clients.jedis.Jedis; public class RedisDistributedLock { private Jedis jedis; public RedisDistributedLock(Jedis jedis) { this.jedis = jedis; } public boolean lock(String key) { // 使用setnx命令实现加锁 // 如果返回值为1,说明获取锁成功 return jedis.setnx(key, "1") == 1; } public void unlock(String key) { // 释放锁只需要删除key jedis.del(key); } } ``` 使用方法: ```java Jedis jedis = new Jedis("localhost"); RedisDistributedLock lock = new RedisDistributedLock(jedis); if (lock.lock("my-key")) { try { // 获取锁成功,执行业务逻辑 } finally { lock.unlock("my-key"); } } else { // 获取锁失败,执行其他操作 } ``` 这只是一个简单的示例,实际应用中可能需要考虑超时释放锁、防止死锁等因素。 ### 回答2: Java Redis分布式锁demo可以通过使用Redis的SET命令和EX命令(有过期时间)来实现。 1. 首先,在Java中引入Redis的Java客户端依赖,例如Jedis或Lettuce。 2. 初始化Redis连接池,创建Redis连接。 3. 编写获取分布式锁的方法,以下是一个简单的示例代码: ```java import redis.clients.jedis.Jedis; public class RedisLockDemo { private static final String LOCK_KEY = "myLock"; private static final int LOCK_EXPIRE_TIME = 10; // 锁的过期时间,单位秒 private Jedis jedis; public RedisLockDemo() { // 初始化Redis连接池和连接 jedis = new Jedis("localhost"); } public boolean acquireLock() { Long result = jedis.setnx(LOCK_KEY, "locked"); if (result == 1) { // 设置锁的过期时间 jedis.expire(LOCK_KEY, LOCK_EXPIRE_TIME); return true; } return false; } public void releaseLock() { jedis.del(LOCK_KEY); } public static void main(String[] args) { RedisLockDemo demo = new RedisLockDemo(); if (demo.acquireLock()) { try { // 成功获取到锁,执行相应的业务逻辑 System.out.println("执行业务逻辑..."); } finally { demo.releaseLock(); } } else { // 未能获取到锁,可以进行相应的处理 System.out.println("获取锁失败,执行其他逻辑..."); } } } ``` 以上代码中,`acquireLock`方法通过Redis的`SETNX`命令尝试从Redis获取锁,如果返回值为1表示成功获取到锁,然后再使用`EXPIRE`命令设置锁的过期时间。`releaseLock`方法则是通过`DEL`命令释放锁。 在`main`方法中,调用`acquireLock`方法获取锁,并在成功获取到锁后执行相应的业务逻辑,最后通过`releaseLock`方法释放锁。 通过以上的简单示例代码,可以实现Java Redis分布式锁的功能。 ### 回答3: Java Redis分布式锁是一种解决多个进程或线程之间访问共享资源时可能发生竞争条件的方法。通过使用Redis作为分布式锁的后端存储,可以确保在任何给定时间只有一个进程或线程可以访问共享资源。 下面是一个Java Redis分布式锁的简单演示示例: ``` import redis.clients.jedis.Jedis; import redis.clients.jedis.params.SetParams; public class RedisDistributedLockDemo { // Redis连接信息 private static final String HOST = "localhost"; private static final int PORT = 6379; // 锁的名称 private static final String LOCK_NAME = "mylock"; // 锁的过期时间(毫秒) private static final long LOCK_EXPIRE_TIME = 5000; public static void main(String[] args) { // 创建Redis连接 Jedis jedis = new Jedis(HOST, PORT); // 尝试获取锁 boolean acquired = acquireLock(jedis); if (acquired) { // 获取到了锁,执行业务逻辑 try { System.out.println("获得了锁,开始执行业务逻辑"); Thread.sleep(2000); // 模拟业务逻辑执行时间 } catch (InterruptedException e) { e.printStackTrace(); } finally { // 释放锁 releaseLock(jedis); } } else { // 没有获取到锁,输出错误信息 System.out.println("未获得锁,执行其他逻辑"); } // 关闭Redis连接 jedis.close(); } private static boolean acquireLock(Jedis jedis) { // 尝试获取锁并设置过期时间 SetParams params = SetParams.setParams().nx().px(LOCK_EXPIRE_TIME); String result = jedis.set(LOCK_NAME, "locked", params); return result != null && result.equals("OK"); } private static void releaseLock(Jedis jedis) { // 释放锁 jedis.del(LOCK_NAME); } } ``` 这个演示示例使用Redis的`set`命令来获取锁,并设置了锁的过期时间,以防止死锁的情况。如果成功获取到锁并执行了业务逻辑,最后释放锁。 总结起来,Java Redis分布式锁的实现主要涉及到以下几个步骤: 1. 创建Redis连接 2. 尝试获取锁 3. 如果成功获取到锁,则执行业务逻辑 4. 释放锁 5. 关闭Redis连接 通过这种方式,我们可以确保在分布式环境中的各个进程或线程之间共享资源的安全访问,避免竞争条件的发生。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值