Runnable是一个接口,不能直接new Runnable()你可在内部用new Thread(){
}Thread也是实现了Runnable接口的。实现了Runnable接口,声明时应该用
Runnable mt1 = new MyThread1()

解决方案 »

  1.   

    呵呵。
    第一:你写的不叫内部类
    第二:Runnable接口你如何直接new ?
          可以这样:
          <<
              new Thread(new MyThread1()).start();
          >>
      

  2.   

    To  kypfos(政治面貌:一世清白):
    我写的是一个匿名内部类,是可以通过new Runnable()来实现Runnable接口的,请你详细的说一下,多谢
      

  3.   

    我运行了下你的程序
      class MyThread1 implements Runnable{
        Thread th = new Thread(this);
        public void run(){
            for (int i = 0; i < 10; i++){
                System.out.println(i);
            }
        }
    是正常的,能打印出0到9。关键是 
    class MyThread2{
        Thread th = new Thread(this.ra);
        Runnable ra = new Runnable(){
            public void run(){
                for (char ch = 65; ch < 70; ch++){
                    System.out.println(ch);
                }
         }
        };
    }有问题,固然
    Runnable ra = new Runnable(){
            public void run(){
                for (char ch = 65; ch < 70; ch++){
                    System.out.println(ch);
                }
         }
        };不对,但jbuilder9确没认识错误和警告信息提示,很奇怪。
    明明new Runnable() 有问题。
      

  4.   

    哦,还真是一个匿名内部类实现了Runnable。
    楼主,你的顺序有问题,你这改再试试:
    在MyThread2中,把Thread th = new Thread(this.ra);
    放到Runnable ra =...的后面。
      

  5.   

    TO Shrewdcat(丧邦&灵猫&潇) :
    <<
    Runnable r = new Runnable() {
        public void run() {}
    }
    >>
    这样做是没有任何问题的。:)
      

  6.   

    To  Shrewdcat(丧邦&灵猫&潇:
    jbuilder9 是不会出编译错误的,因为这句话是合法的,它是声明了一个匿名内部类,这个内部类实现了Runnable接口。
      

  7.   

    这样结果就完全正确了:public class RunnableTest{
        public static void main(String[] args){
            MyThread1 mt1 = new MyThread1();
            MyThread2 mt2 = new MyThread2();
            mt2.th.start();
            mt1.th.start();
        }
    }
    class MyThread1 implements Runnable{
        Thread th = new Thread(this);
        public void run(){
            for (int i = 0; i < 10; i++){
                System.out.println(i);
            }
        }
    }
    class MyThread2{
        //Thread th = new Thread(this.ra);
        Runnable ra = new Runnable(){
            public void run(){
                for (char ch = 65; ch < 70; ch++){
                    System.out.println(ch);
                }
         }
        };
        Thread th = new Thread(this.ra);}
    xiaohaiz(老土进城,两眼通红) 还是慧眼。
      

  8.   

    To xiaohaiz(老土进城,两眼通红);
       你的这个建议可以,多谢指教,能不能说说原因呢
      

  9.   

    呵呵,俺们先来这么看看。假设我们做一个A.java,这样:
    << (A)
    public class A {
        Thread th = new Thread(ra);
        Runnable ra = new Runnable() {
            public void run() {}
        };
    }
    >>
    上面有问题吗?有:编译就会出现“ illegal forward reference”错误,因为你的初始化顺序有问题。但是楼主偏偏在new Thread(ra)的地方写成了new Thread(this.ra),变成了这样:
    << (B)
    public class A {
        Thread th = new Thread(this.ra);  // -- NOTICE HERE.
        Runnable ra = new Runnable() {
            public void run() {}
        };
    }
    >>
    俺们现在来看看这样的初始化顺序,实际上上面的顺序可以演化为这样:
    << (C)
    public class A {
        Thread th;
        Runnable ra;
        {
            th = new Thread(ra);
            ra = new Runnable() {
                public void run();
            };
        }
    }
    >>
    (B)和(C)的字节码是一样的。我们把字节码反编译也放在下面:
    <<
    public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   new     #2; //class Thread
       8:   dup
       9:   aload_0
       10:  getfield        #3; //Field ra:Ljava/lang/Runnable;
       13:  invokespecial   #4; //Method java/lang/Thread."<init>":(Ljava/lang/Runna
    ble;)V
       16:  putfield        #5; //Field th:Ljava/lang/Thread;
       19:  aload_0
       20:  new     #6; //class A$1
       23:  dup
       24:  aload_0
       25:  invokespecial   #7; //Method A$1."<init>":(LA;)V
       28:  putfield        #3; //Field ra:Ljava/lang/Runnable;
       31:  return
    }
    >>
    10:getfield取到的是null。呵呵。走到这里,大家也应该看明白了吧?关键看(C),实际上你在构造
    Thread th = new Thread(ra)的时候,ra现在还是null,所以你构造了一个new Thread(null),这就是为什么你编译没有问题但是运行结果有问题。如果俺们把顺序交换,变成这样:
    << (D)
    public class A {
        Runnable ra = new Runnable() {
            public void run() {}
        };
        Thread th = new Thread(ra);}
    >>
    这样在初始化的时候就变成这样:
    << (E)
    public class A {
        Runnable ra;
        Thread th;
        {
            ra = new Runnable() {public void run(){}};
            th = new Thread(ra);
        }
    }
    >>
    这样自然就没有问题了。(E)的字节码如下:
    <<
    public A();
      Code:
       0:   aload_0
       1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
       4:   aload_0
       5:   new     #2; //class A$1
       8:   dup
       9:   aload_0
       10:  invokespecial   #3; //Method A$1."<init>":(LA;)V
       13:  putfield        #4; //Field ra:Ljava/lang/Runnable;
       16:  aload_0
       17:  new     #5; //class Thread
       20:  dup
       21:  aload_0
       22:  getfield        #4; //Field ra:Ljava/lang/Runnable;
       25:  invokespecial   #6; //Method java/lang/Thread."<init>":(Ljava/lang/Runna
    ble;)V
       28:  putfield        #7; //Field th:Ljava/lang/Thread;
       31:  return
    }
    >>
    22:getfield取到的是Field ra.