0

我有一个 java 类 SortTest,其中包含实现接口 Sorter 的子类。我一直在 Eclipse 中工作,但我需要在 UNIX 中编译和运行,这样我才能传递命令行参数。所以我一直在访问我的 .java 文件正在使用的目录

cd Documents/workspace/csc220/src/prog09

然后我编译我的类和接口使用

javac Sorter.java SortTest.java

没有问题。但是,当我尝试运行时

java SortTest 10 //10 is an arbitrary argument

我收到此错误:

Exception in thread "main" java.lang.NoClassDefFoundError: SortTest/java
Caused by: java.lang.ClassNotFoundException: SortTest.java
at java.net.URLClassLoader$1.run(URLClassLoader.java:202)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
at java.lang.ClassLoader.loadClass(ClassLoader.java:247)

我查看了其他似乎表明这可能是 Sorter 的编译时/运行时可用性问题的线程,但错误只提到了 SortTest,我觉得这很混乱。我该如何解决这个问题?它不依赖于我的实际代码,是吗?

编辑:这是 SortTest.java 的代码:

package prog09;
import java.util.Random;

public class SortTest<E extends Comparable<E>> {
  public void test (Sorter<E> sorter, E[] array) {
    E[] copy = array.clone();
    sorter.sort(copy);
    System.out.println(sorter);
    for (int i = 0; i < copy.length; i++)
      System.out.print(copy[i] + " ");
    System.out.println();
  }

  public static void main (String[] args) {
    Integer[] array = { 3, 1, 4, 1, 5, 9, 2, 6 };
    int size = 0;

    try{
        size = Integer.parseInt(args[0]);
    }catch(NumberFormatException e){
        System.out.println("Your argument was not an integer! Quitting program...");
        return;
    }


    if (args.length > 0) {
      // Print out command line argument if there is one.
      System.out.println("args[0] = " + args[0]);

      // Create a random object to call random.nextInt() on.
      Random random = new Random(0);

      // Make array.length equal to args[0] and fill it with random
      // integers:
      for(int i = 0; i < size; i++){
          array[i] = random.nextInt();
      }
    }
    //print out the array if array.length <= 100
    if(array.length <= 100){
        System.out.printf("[ ");
        for(int i = 0; i < array.length; i++){
            System.out.printf(array[i]+" ");
        }
        System.out.printf("]");
    }

    SortTest<Integer> tester = new SortTest<Integer>();
    tester.test(new InsertionSort<Integer>(), array);
     tester.test(new HeapSort<Integer>(), array);
     tester.test(new QuickSort<Integer>(), array);
     tester.test(new MergeSort<Integer>(), array);
  }
}

class InsertionSort<E extends Comparable<E>>
  implements Sorter<E> {
  public void sort (E[] array) {
    for (int n = 0; n < array.length; n++) {
      E data = array[n];
      int i = n;
      // while array[i-1] > data move array[i-1] to array[i] and
      // decrement i
      while(i > 0 && array[i-1].compareTo(data) > 0){
          array[i] = array[i-1];
          i--;
      }
      array[i] = data;
    }
  }
}

class HeapSort<E extends Comparable<E>>
  implements Sorter<E> {

  private E[] array;

  private void swap (int i, int j) {
    E data = array[i];
    array[i] = array[j];
    array[j] = data;
  }

  public void sort (E[] array) {
    this.array = array;

    for (int i = parent(array.length - 1); i >= 0; i--)
      swapDown(i, array.length - 1);

    for (int n = array.length - 1; n >= 0; n--) {
      swap(0, n);
      swapDown(0, n - 1);
    }
  }

  public void swapDown (int root, int end) {
    // Calculate the left child of root.
    int leftChild = 2*root + 1;
    // while the left child is still in the array
    //   calculate the right child
    //   if the right child is in the array and 
    //      it is bigger than than the left child
    //     bigger child is right child
    //   else
    //     bigger child is left child
    //   if the root is not less than the bigger child
    //     return
    //   swap the root with the bigger child
    //   update root and calculate left child
    while(leftChild < end){
        int rightChild = 2*root + 2;
        int bigChild;
        if(rightChild < end && array[rightChild].compareTo(array[leftChild]) > 0){
            bigChild = rightChild;
        }else{
            bigChild = leftChild;
        }
        if(!(array[root].compareTo(array[bigChild]) < 0)){
            return;
        }
        swap(root, bigChild);
        root = bigChild;
        leftChild = 2*root + 1;
    }
  }

  private int left (int i) { return 2 * i + 1; }
  private int right (int i) { return 2 * i + 2; }
  private int parent (int i) { return (i - 1) / 2; }
}

class QuickSort<E extends Comparable<E>>
  implements Sorter<E> {

  private E[] array;
  private void swap (int i, int j) {
    E data = array[i];
    array[i] = array[j];
    array[j] = data;
  }

  public void sort (E[] array) {
    this.array = array;
    sort(0, array.length-1);
  }

  private void sort(int left, int right) {
    if (left >= right)
      return;

    swap(left, (left + right) / 2);

    E pivot = array[left];
    int a = left + 1;
    int b = right;
    while (a <= b) {
      // Move a forward if array[a] <= pivot
        if(!(array[a].compareTo(pivot) > 0)){
            a++;
        }else
      // Move b backward if array[b] > pivot
        if(array[b].compareTo(pivot) > 0){
            b--;
        }else
      // Otherwise swap array[a] and array[b]
        swap(a,b);

    }

    swap(left, b);

    sort(left, b-1);
    sort(b+1, right);
  }
}

class MergeSort<E extends Comparable<E>>
  implements Sorter<E> {

  private E[] array, array2;

  public void sort (E[] array) {
    this.array = array;
    array2 = array.clone();
    sort(0, array.length-1);
  }

  private void sort(int left, int right) {
    if (left >= right)
      return;

    int middle = (left + right) / 2;
    sort(left, middle);
    sort(middle+1, right);

    int i = left;
    int a = left;
    int b = middle+1;
    while (a <= middle || b <= right) {
      // If both a <= middle and b <= right
      // copy the smaller of array[a] or array[b] to array2[i]
      // Otherwise just copy the remaining elements to array2
        if(a <= middle && b <= right){
            if(array[a].compareTo(array[b]) < 0){
                array2[i] = array[a];
                a++;
            }else{
                array2[i] = array[b];
                b++;
            }
            i++;
        }else{
            if(a > middle)
                System.arraycopy(array, b, array2, i, array.length-b-1);
            else
                System.arraycopy(array, a, array2, i, middle-a+1);
            break;
        }
    }

    System.arraycopy(array2, left, array, left, right - left + 1);
  }
}

这是 Sorter.java:

package prog09;

public interface Sorter<E extends Comparable<E>> {
    void sort (E[] array);
}

这是我java -cp prog09 SortTest从父目录运行时收到的错误消息:

Exception in thread "main" java.lang.NoClassDefFoundError: SortTest (wrong name: prog09/SortTest)
    at java.lang.ClassLoader.defineClass1(Native Method)
    at java.lang.ClassLoader.defineClassCond(ClassLoader.java:631)
    at java.lang.ClassLoader.defineClass(ClassLoader.java:615)
    at java.security.SecureClassLoader.defineClass(SecureClassLoader.java:141)
    at java.net.URLClassLoader.defineClass(URLClassLoader.java:283)
    at java.net.URLClassLoader.access$000(URLClassLoader.java:58)
    at java.net.URLClassLoader$1.run(URLClassLoader.java:197)
    at java.security.AccessController.doPrivileged(Native Method)
    at java.net.URLClassLoader.findClass(URLClassLoader.java:190)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:306)
    at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:301)
    at java.lang.ClassLoader.loadClass(ClassLoader.java:247)
4

1 回答 1

1
  1. 确保 Sorter 和 SortTest 源文件都在默认包空间中(即package prog9代码中没有语句。
  2. 假设 SortTest 有 main,verifyls -l SortTest.class是在当前目录中。
  3. 验证java命令是否正在运行/usr/bin/java (你说你在 Mac 上,而 darwin 有一个稍微复杂的 JAVA_HOME 管理环境)而不是其他东西。
  4. java -classpath . SortTest,告诉我们会发生什么。

OP 通过删除将这两个文件放入默认命名空间,package prog09并且它“工作”。

从命令行,保留package prog09原位,可以执行以下操作:

mkdir prog09
javac Sorter.java SortTest.java
mv Sorter.class SortTest.class prog09
java -classpath . prog09.SortTest
于 2013-11-03T19:17:58.700 回答