使用==操作符比较命令行参数args[0]和字符串返回“Invalid type"

运行程序接收一个来自命令行的字符串参数(取值1,2,3,4),根据参数执行对应语句块。
由于未能判断字符串内容是否相同导致代码if语句块代码失效,怎么也看不到schedule方法的效果,
以下是错误代码:

/*
 * DemoTimer.java -- JDK 1.8
 */

package timer;


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Timer;
import java.util.TimerTask;

/**
 * Description:
 * <p>
 * <p>
 * @author unascribed
 * @date 2019-04-01 Mon PM 13:55:59
 */

public class DemoTimer {
    public static void main(String[] args) {
        // 1.创建一个Timer实例,关联线程不能是daemon(守护/后台)线程
        Timer timer = new Timer();
        // 2.创建一个MyTimerTask实例
        DemoTimerTask myTimerTask = new DemoTimerTask("No.1");
        // 3.通过Timer定时定频率调用myTimerTask的业务代码
        // 如第一次执行是在当前的两秒之后,之后每个一秒执行一次
        // timer.schedule(myTimerTask, 2000L, 1000L);

        Calendar calendar = Calendar.getInstance(); // 通过静态工厂方法创建Calendar实例
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期格式
        System.out.println("Current time is : " + sdf.format(calendar.getTime())); // 在schedule调度任务之前输出当前时间
        calendar.add(Calendar.SECOND, 3); // 当前时间加3秒

        String s = args[0];

        if (s == "1") {
            myTimerTask.setName("schedule1");
            timer.schedule(myTimerTask, calendar.getTime());
        } else if (s == "2")) {
            myTimerTask.setName("schedule2");
            timer.schedule(myTimerTask, calendar.getTime(), 2000);
        } else if (s == "3")) {
            myTimerTask.setName("schedule3");
            timer.schedule(myTimerTask, 3000);
        } else if (s == "4")) {
            myTimerTask.setName("schedule4");
            timer.schedule(myTimerTask, 3000, 2000);
        } else {
        
        }
    }
}

class DemoTimerTask extends TimerTask {

    String name; // 任务名

    public DemoTimerTask(String name) {
        this.name = name;
    }

    @Override
    public void run() {
            // 以yyyy-MM-dd HH:mm:ss打印执行时间
            // 如 2016-11-11 00:00:00
            Calendar calendar = Calendar.getInstance(); // 通过静态工厂方法创建Calendar实例
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); // 定义日期格式
            System.out.println("Current time is : " + sdf.format(calendar.getTime()));        
            // 打印当前name的内容
            System.out.println("Current exec name is : " + name);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}
  • 尝试一
    • 首先想到是不是引用的问题,这里传递了一份引用:
String s = args[0];

于是删去变量s,将下面语句中原来的s变量全部替换成args[0],但是这是无效的。

  • 实际上,变量引用再一个方法的作用域内是没错,测试以下代码:
    @Test
    public void test() {
        String s = "1"; // L1
        // String s = new String("1"); // L2
        String t = s;
        System.out.println(s == t);
    }

L1或L2的测试返回值都为true,说明t对s的引用拿到了s的真实地址,排除变量引用使用不当的可能性。

  • 再构造一个案例:
    @Test
    public void test() {
        String[] arr = {"1"};
        String t = arr[0];
        System.out.println(t == "1");
    }

测试结果为true,也排除了代码块内部数组干扰的可能性。

  • 最后mock了以下args的形式,模仿错误代码编写,传入数组String[] s = {"1"}
public class DemoTimer {
    public static void main(String[] args) {
        String[] s = {"1"};
        DemoTimer demoTimer = new DemoTimer();
        demoTimer.test1(s);
        DemoTimer.test2(s);
        DemoTimer.test3(s);
    }
    
    public void test1(String[] arr) {
        System.out.println(arr[0] == "1"); // 预期true,实际true
    }
    
    public static void test2(String[] arr) {
        System.out.println(arr[0] == "1"); // 预期true, 实际true
    }
    
}

至此,彻底断了使用==的念想。

  • 尝试二
    既然是比较内容是否相同,那么自然会想到用equals()方法。

注意:equals()方法是从Object类继承的,String重写了她。

        if (s.equals("1")) {
            myTimerTask.setName("schedule1");
            timer.schedule(myTimerTask, calendar.getTime());
        } else if (s.equals("2")) {
            myTimerTask.setName("schedule2");
            timer.schedule(myTimerTask, calendar.getTime(), 2000);
        } else if (s.equals("3")) {
            myTimerTask.setName("schedule3");
            timer.schedule(myTimerTask, 3000);
        } else if (s.equals("4")) {
            myTimerTask.setName("schedule4");
            timer.schedule(myTimerTask, 3000, 2000);
        }

这样写,代码不再是Dead Code了。

总结

原文地址:https://www.cnblogs.com/xsjzhao/p/10636510.html