V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Scicomath
V2EX  ›  Java

<算法 第四版>的 Java 环境配置问题: 警告: [deprecation] In 中的 readInts(String)已过时

  •  
  •   Scicomath · 2016-08-25 20:02:39 +08:00 · 10202 次点击
    这是一个创建于 3003 天前的主题,其中的信息可能已经有所发展或是发生改变。

    最近在看<算法 第四版>, 这本书是基于 Java 写的. 在配置 Java 环境的时候遇到一些问题. 由于之前没用过 Java, 所以来问一下到底是什么情况.

    问题背景:

    • 系统: Archlinux 64 位
    • jdk: jdk7-openjdk, 版本: 在终端下运行javac -version输出的是javac 1.7.0_111

    首先, 这本书的作者定义一些自己写的输入输出库, 在书的官网中给出了库文件algs4.jar. 我下载了库文件, 并且按照官网的说明, 讲文件放在了~/algs4/下面, 并且在.bashrc 中修改了 CLASSPATH 环境变量:

    export CLASSPATH=$CLASSPATH:~/algs4/algs4.jar
    

    然后试着编译运行一个书中一个简单的示例程序:

    import edu.princeton.cs.algs4.In;
    import edu.princeton.cs.algs4.StdIn;
    import edu.princeton.cs.algs4.StdOut;
    import java.util.Arrays;
    
    public class BinarySearch
    {
        public static int rank(int key, int[] a)
        {
    	int lo = 0;
    	int hi = a.length - 1;
    	while (lo <= hi) {
    	    int mid = lo + (hi - lo) / 2;
    	    if (key < a[mid])
    		hi = mid - 1;
    	    else if (key > a[mid])
    		lo = mid + 1;
    	    else
    		return mid;
    	}
    	return -1;
        }
    
        public static void main(String[] args)
        {
    	int[] whitelist = In.readInts(args[0]);
    
    	Arrays.sort(whitelist);
    
    	while (!StdIn.isEmpty()) {
    	    int key = StdIn.readInt();
    	    if (rank(key, whitelist) == -1)
    		StdOut.println(key);
    	}
        }
    }
    
    

    其中用到了作者提供的几个函数: In, StdIn, StdOut. 但是我在编译的时候报错如下:

    $ javac BinarySearch.java 
    注: BinarySearch.java 使用或覆盖了已过时的 API 。
    注: 有关详细信息, 请使用 -Xlint:deprecation 重新编译。
    

    然后我按照提示添加了-Xlint:deprecation选项, 再次编译:

    $ javac BinarySearch.java -Xlint:deprecation
    BinarySearch.java:26: 警告: [deprecation] In 中的 readInts(String)已过时
    	int[] whitelist = In.readInts(args[0]);
    	                    ^
    1 个警告
    

    虽然提示警告但是仍然生成了BinarySearch.class文件, 于是我试着运行了一下, 果然有问题:

    $ java BinarySearch.class
    错误: 找不到或无法加载主类 BinarySearch.class
    

    这到底是什么问题呢? 是因为 JDK 太新了吗?

    PS:我之前安装的是 JDK8, 后来出现了上面的问题, 然后我又换成了 JDK7, 但是问题依然存在.

    22 条回复    2020-07-09 17:54:04 +08:00
    halfcoder
        1
    halfcoder  
       2016-08-25 20:22:23 +08:00
    只是警告不是错误仍然能够生成 class 是正常的,警告只是提醒希望不要再继续使用这个 api 而已

    java 运行 class 文件时不需要带后缀
    echo1937
        2
    echo1937  
       2016-08-25 20:26:40 +08:00
    不应该是$ java BinarySearch 吗?
    whatot
        3
    whatot  
       2016-08-25 20:27:17 +08:00
    /**
    * Reads all doubles from a file and returns them as
    * an array of doubles.
    *
    * @param filename the name of the file
    * @return the doubles in the file
    * @deprecated Replaced by <tt>new In(filename)</tt>.{@link #readAllDoubles()}.
    */
    @Deprecated
    public static double[] readDoubles(String filename) {
    return new In(filename).readAllDoubles();
    }


    源代码里面都是说的很清楚吗??
    whatot
        4
    whatot  
       2016-08-25 20:28:53 +08:00
    貌似贴错了,应该是下面一段的 readInts
    Scicomath
        5
    Scicomath  
    OP
       2016-08-25 20:35:31 +08:00
    @halfcoder 我当时一时短路了. 我之前是运行的 java BinarySearch, 但是还是报错:
    $ java BinarySearch
    Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0
    at BinarySearch.main(BinarySearch.java:26)

    我现在仔细看了下报错信息, 发现这个报错不是编译的问题. 原因是这个程序需要外部文件做输入. 从官网下载了两个文件: tinyT.txt tinyW.txt. 然后运行:
    java BinarySearch tinyW.txt < tinyT.txt
    结果成功运行!

    这是一个低级错误, 书上的例子就是类似上面的输入. 估计是之前编译的时候提示警告已过时, 让我心理上感觉编译有问题, 于是立刻随便运行了一下, 结果发现报错, 就没有自己看报错提示就想当然的认为是编译出了问题.

    最后, 非常感谢你的回复!
    Scicomath
        6
    Scicomath  
    OP
       2016-08-25 20:43:53 +08:00
    @whatot 恩, 我刚刚也自己看了下它的源代码, 里面确实已经写出了:
    /**
    * Reads all integers from a file and returns them as
    * an array of integers.
    *
    * @param filename the name of the file
    * @return the integers in the file
    * @deprecated Replaced by <tt>new In(filename)</tt>.{@link #readAllInts()}.
    */
    @Deprecated
    public static int[] readInts(String filename) {
    return new In(filename).readAllInts();
    }

    然后我根据它的提示, 重新修改了代码:
    int[] whitelist = In.readInts(args[0]);
    改为:
    int[] whitelist = new In(args[0]).readAllInts();

    重新编译, 运行, 没有任何错误.
    谢谢了!
    feiyuanqiu
        7
    feiyuanqiu  
       2016-08-25 20:45:01 +08:00
    书出的比较早,我是 13 年买的,所以书里面的代码可能更新了

    建议到此书的官网看看的最新版的代码示例 http://algs4.cs.princeton.edu/home/
    feiyuanqiu
        8
    feiyuanqiu  
       2016-08-25 20:46:59 +08:00
    事实上 algorithms 这本书的全部英文版内容都被作者放到网站上了,可以试试直接读英文版,不用买书了
    Scicomath
        9
    Scicomath  
    OP
       2016-08-25 20:48:27 +08:00
    @feiyuanqiu 恩, 里面的代码确实已经修改了, 修改后没有问题.
    Scicomath
        10
    Scicomath  
    OP
       2016-08-25 20:56:57 +08:00
    @feiyuanqiu 看了下发现真的是的. 另外, 我也没有买书. 下的网上一个中文版 PDF, 但是发现不完整. 后来又下了一个英文版 PDF. :)
    arrow2015
        11
    arrow2015  
       2016-08-25 23:18:52 +08:00 via Android
    这本书内示例程序运行让我头疼. 因此我没有多阅读这本书,只看了链表那几节的内容。排序算法那几个代码片段我拷贝到 ide 里运行过,是在程序里写好 int 数组运行的,而非终端输入几个整数。需要从终端读取键盘输入这个功能的示例我没运行成功过。看到书内不少示例需要从终端读取输入,我没有多读这本书。
    Scicomath
        12
    Scicomath  
    OP
       2016-08-25 23:28:45 +08:00
    @arrow2015 你是在 Win 系统下吗? 我在 linux 下,按照上面的方法设置后就完全没有问题了。 具体是什么问题呢? 应该有错误提示吧, 也可以贴出来看看, 说不定是很简的问题。 我之前遇到上面的问题也很烦,都不想看这本书了,最后问题解决了,也没有想象中那么麻烦。
    ragonci
        13
    ragonci  
       2016-08-26 09:26:08 +08:00 via Android
    @arrow2015 和你有一样的困惑, win 下命令行导入参数然后输出结果到另一个参数指向的文件,不知道同等的做法在诸如 intellij 之类的 ide 下是怎么做的,所以一直卡在头几页没法继续下去。。
    arrow2015
        14
    arrow2015  
       2016-08-26 18:43:23 +08:00 via Android
    @Scicomath @ragonci 今天在 Intellij IDEA 上试了 39 页 Average 代码,一次成功了。 idea 给项目添加 algs4.jar 依赖不难。感觉可以继续读了。。
    arrow2015
        15
    arrow2015  
       2016-08-26 18:47:54 +08:00 via Android
    这次是从 idea 终端窗口输入 4 个数值,然后按 Ctrl-D 键输出了 4 个数的平均值。(^o^)v
    arrow2015
        16
    arrow2015  
       2016-08-26 19:01:50 +08:00
    @Scicomath 编译: javac -cp algs4.jar:. Average.java 运行:java -cp algs4.jar:. Average. 终端编译&运行每次要带 -cp algs4.jar 好麻烦..
    arrow2015
        17
    arrow2015  
       2016-08-26 19:07:48 +08:00
    参考楼主帖子把 algs4.jar 的文件路径赋值给 CLASSPATH 环境变量后, 编译运行可以省略掉-cp algs4.jar 了
    ragonci
        18
    ragonci  
       2016-08-26 21:07:49 +08:00
    @arrow2015 能详细说说怎么在 intellij 弄命令行参数么。。我编译倒是通过了
    arrow2015
        19
    arrow2015  
       2016-08-27 01:20:32 +08:00
    @ragonci idea 菜单 Run>Edit Configurations..>Program arguments. 但是这里输入的参数有局限。 http://stackoverflow.com/questions/12018813/passing-string-buffer-to-java-program-in-intellij-debug-run#answer-12019500 根据这个回答,像本贴楼主 tinyW.txt < tinyT.txt 这样重定向是不可能的。 idea 可以读取 args[0]为 tinyW.txt 并构造出 whitelist 数组,但是程序会卡在 while 循环的判断里。 tinyT.txt 不能重定向给 StdIn 。
    ragonci
        20
    ragonci  
       2016-08-27 13:33:25 +08:00 via Android
    @arrow2015 好的,谢谢,看起来只能用 java io 了
    flaneur0py
        21
    flaneur0py  
       2016-09-10 12:50:31 +08:00
    其实不需要用文件输入,输入完字符之后回车+(ctrl+d)就可以
    ljw97
        22
    ljw97  
       2020-07-09 17:54:04 +08:00
    哈哈,同一个难住了 2020 年的我了。。感谢的大家
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   4449 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 23ms · UTC 10:06 · PVG 18:06 · LAX 02:06 · JFK 05:06
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.