当对象超出创建对象的范围时,如何在对象上调用该方法

时间:2013-10-22 00:21:44

标签: java object methods invocation

我在一个名为actors的单独类中有一个名为“filmList”的ArrayList,我想在switch中使用case 2来调用newActor.filmList.get(i);但我不断从编译器中得到object may not be initialized错误。如果我在开关盒1中放入相同的线它工作正常,但在案例2中我得到错误。有人可以告诉我如何从构造函数创建newActor对象的外部调用对象的方法,我将永远感激,它正在努力,我的讲师很难解释事情。感谢。

public class ActorsMain {

public static void main(String[] args) {

    Scanner kb = new Scanner(System.in);

    String fName="";
    String lName="";
    String address="";
    int age;
    String filmEntry="";
    String code="";


    ArrayList actors = new ArrayList(); 
    ArrayList films = new ArrayList();
    int choice=0;
    while(choice!=3){
    System.out.println("Make your selection.\n1. Add Actor\n2. List Actors");
    choice=kb.nextInt();

    switch (choice){

    case 1:
            System.out.println("\nPlease enter the actors first name:");
            fName=kb.next();
            System.out.println("Please enter the actors second name:");
            lName=kb.next();
            System.out.println("Please enter the actors address:");
            address=kb.next();
            System.out.println("Please enter the actors age:");
            age=kb.nextInt();
            kb.nextLine();

            for(int a=0;a<10;a++){
            System.out.println("Please enter the actors film.\nType 'Stop' to stop entering films.");
            filmEntry=kb.nextLine();
            //kb.nextLine();
                if(filmEntry.equalsIgnoreCase("stop")){
                    break;
                }
                else {

                    Films filmObject = new Films(filmEntry,code);
                    films.add(filmObject);
                }
            }


            Actors newActor = new Actors(fName,lName,address,age);
            actors.add(newActor);

            newActor.setFilm(films);
            films.clear();
            break;

    case 2:

        break; 


    }
    }





}       

}

3 个答案:

答案 0 :(得分:0)

我猜你的Actor类有一个名为filmList的ArrayList,你想从某个位置获取它的值。如果是这种情况,您应该在Actor类中创建一个getFilmListIndex(int pos)方法,该方法接收索引值并返回您的电影列表存储的任何对象。假设你的filmList存储了String,它可能看起来像这样。

  public String getFilmListIndex(int pos)
      {
         return filmList.get(i);
      }

然后从您的ActorMain类中调用此方法。

  String result = newActor.getFilmListIndex(i);

答案 1 :(得分:0)

声明时,

age未初始化。在情况1中它将被设置,但在情况2中,尚不清楚它是否已被设置。

你可以在声明它时给它指定一个虚拟值,但一般来说,更好的做法是将变量主要用于实际使用它们的位置。有一个有效的值

这会建议将所有的actor细节放在一个单独的方法中,或者在{}花括号内部(不那么好),并且只在你赋值时声明它们。使用未定义,虚拟或过时值的可访问变量可证明不太正确而不是仅使用与其值有效的范围相同的范围声明变量&amp;适用。

答案 2 :(得分:0)

您必须在switch语句的范围之外声明newActor。在您的交换机的案例2中,newActor不存在。

int c = 0;
switch (c) {
    case 1:
        Object obj = new Object();
        break;
    case 2:
        System.out.println(obj.toString()); // obj only exists in case 1
        break;
}

这实际上有点奇怪,也许其他人可以解释原因,但是你得到的错误似乎是switch语句特有的。如果您尝试执行以下操作:

int c = 0;
if (c == 1) {
    Object obj = new Object();
} else if (c == 2) {
    System.out.println(obj.toString());
}

你会得到一个不同的错误,上面写着“找不到符号”,这个错误就更重要了。显然,交换机内部的案例共享范围,以便他们可以“看到彼此”。我认为这与sans-break跌倒有关。开关都是一个块,案例只确定入口点。

我不确定你要做什么告诉你在哪里放置你的newActor声明,但现在问题是你的交换机中的情况2无法使用它。它只存在于案例1中。

此外,您不应该使用开关进行如此长的声明。你至少应该重构它所以它使用if语句。开关不仅仅适用于此类事物。它们适用于长期条件,每种情况都有很多可能性和小陈述:

char operator = '*';
int leftNumber = 5;
int rightNumber = 9;

switch (operator) {
    case '+': System.out.println(leftNumber + rightNumber);
              break;
    case '-': System.out.println(leftNumber - rightNumber);
              break;
    case '*': System.out.println(leftNumber * rightNumber);
              break;
    case '/': System.out.println(leftNumber / rightNumber);
              break;
    case '^': System.out.println(Math.pow(leftNumber, rightNumber));
              break;
    default:  System.out.println("Unknown operator");
}

从长远来看,您没有将类型参数传递给ArrayLists。除非您这样说,否则Java不知道您的ArrayLists包含Actors和Films:

ArrayList<Actors> actors = new ArrayList<Actors>();

ArrayLists和其他泛型应该使用括号参数<E>进行初始化,其中E是数组中元素的所需类类型。

类型参数有点像扩展类。 ArrayList类将在整个源代码中包含E,当您将Actor传递给E参数时,E将替换为Actor。

class ArrayList<E> {
    Object[] array = new Object[some_length];
    public E get(int index) {
        return (E)array[index];
    }
}

变为

class ArrayList<Actor> {
    Object[] array = new Object[some_length];
    public Actor get(int index) {
        return (Actor)array[index];
    }
}

请注意,即使这样,在应用程序运行时,Java是否知道ArrayList包含Actors仍然是模糊的,因为泛型的实现方式。它们是使用称为擦除的东西实现的。在运行时,无法知道ArrayList是Actor类型。

如果使用type参数声明它们,您将能够使用get()作为代码中的Actors和Films来访问它们的元素,而这些元素现在是您无法使用的。

换句话说,你可以这样做:

System.out.println(actors.get(aIndex).filmList.get(fIndex));

看起来你开始尝试在案例2下做,但你现在也无法做到。如果没有<Actor><Film>,它将告诉您“无法找到符号”或“不兼容的类型”,因为ArrayList包含没有type参数的Object数组。 (它仍然是带有类型参数的Object数组,但您可以像传入的类型一样使用它。)