首先程序如下:import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Exam5_8 extends Applet implements ItemListener
{
Choice cho;
TextField text;

public void init()
{
text=new TextField(10);
cho=new Choice();
cho.add("red");
cho.add("yellow");
cho.add("green");
cho.add("blue");
add(cho);
add(text);
cho.addItemListener(this);
}
public void itemStateChanged(ItemEvent e)
{
if(e.getItemSelectable()==cho)
String str=cho.getSelectedItem();
text.setText(str);


}
}
*这个程序在红色地方会报错:
Syntax error, insert ";" to complete Statement
Syntax error, insert "AssignmentOperator ArrayInitializer" to complete ArrayInitializerAssignement真是古怪的错误,然后只要把if下面的语句加上{},程序就能正常运行了,这是为什么啊
还有就是,如果去掉if语句,程序也能运行
在就是把String str定义在类的成员变量,而不定义在类方法里面,也可以运行,
太古怪了,实在搞不懂,望高手现身回答下,谢了!

解决方案 »

  1.   

    我是这么理解的,勉强说的过去。if(e.getItemSelectable()==cho) 
    String str=cho.getSelectedItem();因为if后面没有花括号,所以只会执行一句,那么你的字符串变量str的作用域就只限于当前的这一条定义语句,定义好之后就没用了,就等着被垃圾收集器回收,编译器会认为这是一条没有意义的定义,就好像除数为0一样,一点意义都没有,所以编译器会报错。但是有了花括号之后就不同了,字符串变量str的作用域被扩大了,只要作用域没有结束,就可以对变量str进行任何操作,虽然你现在只有一条定义语句,但编译器会认为你可能以后会在后面添加对于str的处理。if(e.getItemSelectable()==cho) 
    {
    String str=cho.getSelectedItem();
    str=new String("...");
    //可以对str进行任何操作
    }
      

  2.   

    感觉ls正解编译器提示
    Syntax error, insert "AssignmentOperator Expression" to complete Assignment
    恰恰是认为在单语句作用域情况下的语法错误 即加入了声明的赋值语句不完整
    有这种判断暗示着编译器不允许此种情况出现。
      

  3.   

    呵呵,真是高手啊,听你讲完了之后,不能说彻底明白了,但是和你有同感了,你的解释和现象好象很吻合的
    另外我还想问个问题,我是刚学JAVA的,有些内容,怎么翻数都没有,所以只能到这来问了,希望你能在给我回答次
    Java的事件类中几乎每个事件类都有返回触发事件源的方法,并且他们还都个公共的getsource()方法可以返回触发事件的事件源,他们之间有什么区别吗,都用getsource()来判断不就行了吗,为什么要那么多啊?好多书上都没给出解释,望高手解释下,谢谢了,另外Button里面的.getActioncommand()与.getLabel()方法什么区别啊,我试了下,觉得返回的都是Button上的字符啊? 
    这些问题困饶了我好半天了,真诚希望详细的解答,我会尽量给高分的.再次谢谢了!真心谢谢了,我会尽量加分的,谢谢了!
      

  4.   

    各位高手,听你们解释后,我又进行了如下改进,将String str一句提到if之前,也就是说提前于if进行定义,扩大它的作用域,然后再在if 里面写上str=......,发现if 下面的一条语句不会报错了,但是setText(str)中的str又会报错,这是为什么啊,难道if里面就不能又单条赋值语句吗,可我试了将str的定义为类的成员变量就一切解决了,看来还是str的作用域问题,可是我将str在方法中提前定义了啊,应该是将它扩大了,为什么还不行呢,讲的又点罗嗦了,希望哪位能在解释下啊,不甚感激!
      

  5.   

    getSource()方法返回的是对象,是ActionEvent类从祖父类java.util.EventObject中继承过来的
    getActioncommand()方法返回的是字符串。该默认值为事件源所对应组件的标签。
    getLabel()方法返回的也是字符串,返回的是组件的标签。getActioncommand()和getLabel()的区别:JButton jbutton_1=new JButton("jbutton");
    JButton jbutton_2=new JButton("jbutton");  //两个按钮标签一样jbutton_1.setActionCommand("jbutton_1");   //设置按钮1的ActionCommand值为"jbutton_1"
    jbutton_2.setActionCommand("jbutton_2");   //设置按钮2的ActionCommand值为"jbutton_2"System.out.println(jbutton_1.getLabel());  //输出:jbutton
    System.out.println(jbutton_2.getLabel());  //输出:jbutton
    System.out.println(jbutton_1.getActionCommand());  //输出:jbutton_1
    System.out.println(jbutton_2.getActionCommand());  //输出:jbutton_2看到这里是不是有点明白了?当两个按钮的标签值一样时,使用getLabel()方法是不能区别事件源的,只有通过事先设置好的ActionCommand才能区别开来,如果懒得设置ActionCommand,就直接用getSource()方法来区别事件源。
      

  6.   


    public   void   itemStateChanged(ItemEvent   e) 

    String str;      //#1
    if(e.getItemSelectable()==cho) 
    str=cho.getSelectedItem();  //#2
    text.setText(str);   //#3
    }在#1行中,你声明了变量str,这里要注意,你只是声明,而没有定义,这时候str没有被初始化
    在#2行中,你的确赋值了,但是如果if中的表示为false呢?#2行就不做了,这时候str仍然没有被初始化。
    在#3行中,由于之前if语句没有做,导致str没有被初始化,这种情况下直接使用是编译器不允许的,所以会报错。简而言之,在使用一个引用前,必须确保任何一种情况下它都是被初始化过的,即必须创建一个对象让他用或者让他指向null。
      

  7.   

    呵呵,些许明白了点,可我想知道,我们平常设计的时候有谁会将两个按钮标签设置成一样啊,那样在界面上就无法区分了,如果设置成不一样的话,那command还有什么用啊,直接返回标签label不就行了吗,归根结底就是这个command一般用在什么地方,有什么特别的用处啊?
    作为一名初学者其实我最搞不清楚的是,既然用e.getsource()可以用在所有的事件类中(因为它们都继承了父类的)那么每个事件类自己的判别事件源的方法不就每什么必要了吗,全用e.getsource()多简洁方便啊!诸如什么e.getItemSelectable(),e.getItemSelectable().equals("")之类的,多麻烦啊!既然存在肯定有它的理由,望高手能给以详细解答了,另外谢谢所有回贴的人,向你们学习中
      

  8.   

    呵呵,了解!一般情况下,如果我定义一个int i;不给它赋值的话,它会默认为0,我还以为这里能默认为空呢,刚试了下,把String str写成String str=new String ("");就能顺利运行了,这么晚了,得到你的帮助,真是谢谢了!好象加分要隔一天,等到明天,我一定给你加分了,再次谢谢了!
      

  9.   

    各位高手,听你们解释后,我又进行了如下改进,将String   str一句提到if之前,也就是说提前于if进行定义,扩大它的作用域,然后再在if   里面写上str=......,发现if   下面的一条语句不会报错了,但是setText(str)中的str又会报错,这是为什么啊,难道if里面就不能又单条赋值语句吗,可我试了将str的定义为类的成员变量就一切解决了,看来还是str的作用域问题,可是我将str在方法中提前定义了啊,应该是将它扩大了,为什么还不行呢,讲的又点罗嗦了,希望哪位能在解释下啊,不甚感激!
    ///////////////////////////////////////////////////////////////////////////////////////////////////
    lz说的报错是这个吧The local variable str may not have been initialized局部变量可能未被初始化初始化一下就好了
    String str="";
      

  10.   

    呵呵,些许明白了点,可我想知道,我们平常设计的时候有谁会将两个按钮标签设置成一样啊,那样在界面上就无法区分了,如果设置成不一样的话,那command还有什么用啊,直接返回标签label不就行了吗,归根结底就是这个command一般用在什么地方,有什么特别的用处啊? 
    作为一名初学者其实我最搞不清楚的是,既然用e.getsource()可以用在所有的事件类中(因为它们都继承了父类的)那么每个事件类自己的判别事件源的方法不就每什么必要了吗,全用e.getsource()多简洁方便啊!诸如什么e.getItemSelectable(),e.getItemSelectable().equals("")之类的,多麻烦啊!既然存在肯定有它的理由,望高手能给以详细解答了,另外谢谢所有回贴的人,向你们学习中
      

  11.   

    好问题 我来试着回答一下吧ActionEvent在构造的时候有一个参数就是String类型的command 
    它有它存在的意义 这个串就指定了与此事件相关联的命令名
    与组件的名称含义是不同的 至于其如何被使用 则因人而异getSource和getItemSelectable诸如此类 getSource显然范围更宽泛
    我想当一个组件有多个事件源的时候 要想确定具体的事件源getSource在这里就不适用了
    比如一个item添加了itemSelect事件监听和鼠标覆盖监听 就必须得用具体的获取事件源方法
    如getItemSelectable
      

  12.   

    还是有点不明白,就拿上面拿个程序来讲吧,里面的if(e.getItemSelectable()==cho)如果我写成 if(e.getsource()==cho)不也行,在什么情况下,非要用e.getItemSelectable()==cho它,而用e.getsource()判断不了啊,望能举例说明之,谢谢了!
      

  13.   

    不好意思 解释失败 貌似没有 getItemSelectable()相当于getSource()方法,一样都是返回触发事件的组件,用来判断是哪个组件产生事件。getSource()方法是EventObject类所提供,而所有事件类都会继承这个类,因此所有的事件均能用getSource()方法来判断到底是哪个组件触发了事件。无法强力解释其存在必要性 弱弱地说一句 可能是为了增加可读性吧
      

  14.   

    楼主问了3个问题。第一个问题显然是逻辑不清晰造成的。你将变量定义在条件分支中,却试图在条件分支以外使用它,那如果条件分支没有执行,变量就得不到定义了。这种明显的逻辑错误,显然是编译器不能接受的。
    合理的逻辑应该是:
    if(e.getItemSelectable()==cho) {
      String str=cho.getSelectedItem(); 
      text.setText(str);
    }
    或者:
    String str = "":
    f(e.getItemSelectable()==cho)
      str=cho.getSelectedItem(); 
    text.setText(str);还有,局部变量是一定要显式初始化才能用的(哪怕初始化为null),只有成员变量才会自动初始化,这是基本常识。第二个问题,你的理解也不对。JAVA把label和command分开设置,这无可厚非呀,本来两者的执行的功能就不一样,label是负责界面显示的,command则是命令标识,两者没有理由一致,更不需要合二为一。同一个界面中,label相同的组件却有不同的行为,这种情况多的是!第三个问题,getSource()是Event类的,getItemSelectable()是ItemEvent类的,两者返回的是同一个东西,都是事件源对象。但是,getSource()返回的是一个Object,要使用getSource()返回的对象往往要向下转型;而getItemSelectable()则明确返回一个ItemSelectable,这样你就可以直接把它当作ItemSelectable来用,直接调用ItemSelectable接口中的方法而无需向下转型,这样更安全。总之,两者各有所用,不存在多余的情况。
      

  15.   

    忍不住再罗索几句。
    楼主善于提出疑问这一点是很好的,但是在态度上,怀疑他人多于怀疑自己。
    实际上,进步往往是从怀疑自己开始的。
    JAVA是一门发展非常成熟的语言,是众多业界精英智慧的结晶,如果那么值得怀疑,它还能存在到今天么?
      

  16.   

    呵呵,太感谢,楼上Dan1980的见解了,其实如果你仔细看的话,我说了既然存在就有存在的理由,我并不是怀疑它的正确性与必要性。只是从一个初学者的的角度去考虑与看待它,如果能得出矛盾是好事啊,因为这样才会激发出不断求知的欲望,因为我知道肯定是自己在哪方面没了解(也就是说我还是在怀疑自己),然后在去看别人正确的解释,而后恍然大悟,这样在加深印象的同时,也可以激发自己对这件事的兴趣(原来它是这样进行处理的啊,难怪呢!)
    说的有点多了,不过我很同意楼上的见解,怀疑应该首先从自己开始,可能是我在表达方面显得过于强烈(没办法,这些问题苦恼我好半天了,显得急噪了些)才会让楼上兄弟对我产生了误解,这里再次对你表示感谢了,虽然对问题只是在表面上理解了,因为还是没涉及到具体的应用,,,不过我会继续努力的,再次谢谢了!
      

  17.   

    LZ不是怀疑JAVA,而是对JAVA的困惑。
    怀疑都是高手的作风,困惑都是初学者的作为。
      

  18.   

    各位,听完你们的解答,深感自己知识的薄弱,其实我自认为看书已经很认真了,但是书上真的对这些东西都没概念啊,好多地方讲的都不深入,要不是我自己乱改程序,也许永远也发现不了这些你们所谓的常识!恳请各位推荐本java方面深入的书籍,把一些事件类以及触发方式讲的在深入些(特别GUI方面),由于我基本上是在自学,所以希望书上能尽可能多的给出些例子!,谢谢了!
      

  19.   

    这个问题就是因为变成习惯不好造成的,只要改成
    public   void   itemStateChanged(ItemEvent   e) 

      if(e.getItemSelectable()==cho)
      {
         String str=cho.getSelectedItem(); 
         text.setText(str); 
      } 

    就可以了,因为if后面如果不加括号的话,就只能与下一行形成条件匹配,这样text.setText(str); 中的str就相当于没有定义了
      

  20.   

    懂了,谢谢了,可以实现了!想请教下,书上说,AWT和Swing有时可以互换,就是我把用AWT写的菜单栏前面都加上J然后写入IMPORT   JAVAX.SWING.*,可以看到效果,也可以写addActionlistener(this),但是用鼠标单击的触发的时候却会报错,这是怎么回事啊,谁能给我个用SWING.编写的菜单栏以及实现吗,谢谢了!我写的是这样的: 
    public   void   init() 
    {JMenuBar   myB=new   JMenuBar(); 
    setJMenuBar(myB); 
    JMenu   m1=new   JMenu("文件(E)"); 
    m1.add(new   JMenuItem("打开")); 
    JMenuItem   m11=new   JMenuItem("保存"); 
    m1.add(m11); 
    m1.add("打印"); 
    m1.addSeparator(); 
    //JMenuItem   exit=new   JMenuItem("退出"); //exit.addActionListener(this); 
    m1.add(exit); 
    m1.addActionListener(this); 
    myB.add(m1); 
    JMenu   m2=new   JMenu("编辑(V)"); 
    m2.add("复制"); 
    JMenu   m21=new   JMenu("颜色"); 
    m21.add("前景色"); 
    m21.add("背景色"); 
    m21.addActionListener(this); 
    m2.add(m21); 
    m2.addSeparator(); 
    //JCheckboxMenuItem   mycmi=new   JCheckboxMenuItem("全选"); 
    //mycmi.addItemListener(this); 
    //m2.add(mycmi); 
    m2.addActionListener(this); 
    myB.add(m2); JMenu   m3=new   JMenu("帮助(H)"); 
    m3.add("关于"); 
    m3.addActionListener(this); 
    myB.add(m3); 
    setVisible(true); 

    public   void   actionPerformed(ActionEvent   e) 
    {if   (e.getActionCommand()=="退出") 
    System.exit(0); 

    可是当我触发的时候却会报错!