【问题标题】:Java: Inheritance, Exeptions and super keywordJava:继承、例外和超级关键字
【发布时间】:2018-03-25 18:57:16
【问题描述】:

我有一个类 Xints 保存在一个数组中:

public class X{
 public int[]        a;
 public boolean[]    allocated;

 //constructor
 public X(int len){
  this.a = new a[len];
  this.a = new allocated[len];
 }


public void save(int tosave) throws ArrayStoreException{
  int pos = 0;

  for(int i=0; i<allocated.length; i++){
    if(allocated[i] == true){
      pos++;
    }
  }

  if(pos == allocated.length){
    throw new ArrayStoreExeption("no free space left");
  }

  a[pos] = tosave;
  allocated[pos] = true;
 }
}

还有我仍然需要实现的 Ysave2 类...

public class Y extends X{

  public void save2(int tosave){

     // to be implemented
  }

}

对于save2,我希望它与save 执行相同的操作,但如果没有剩余可用空间或发生 ArrayStoreException,那么我希望数组的大小加倍,然后插入参数到数组。

如果我这样做:

try{
  super.save(tosave);   // If no exception is thrown, does it save 'tosave'?

}catch(ArrayStoreExeption e){
  System.out.println("noe free sapce left");
}

我的第一个问题是:如果try块没有触发异常,catch块之后的代码会执行吗? 如果没有更多空间或抛出异常,我不知道将这段代码保存在哪里,这会使数组大小加倍。

有人可以帮忙吗?

编辑: 我可以在 catch 块内放置使数组加倍的代码吗?

【问题讨论】:

  • catch 只会在 try 块抛出 ArrayStoreException 时执行。如果您希望您的代码始终执行,您可以使用 finally docs.oracle.com/javase/tutorial/essential/exceptions/…
  • 我只希望在抛出异常时执行一段特定的代码,否则我希望它在 try 块内执行操作

标签: java arrays inheritance exception


【解决方案1】:
  1. 您发布的代码有许多语法错误。如果这个答案不让您满意,我建议您修复并重新发布。

  2. 是的,您可以实现代码来扩展子类的 catch 块内的数组。它需要调用超类的save 方法

  3. 您的子类可能应该覆盖save 方法,而不是创建一个新的save2 方法

  4. 使用布尔数组没有多大意义。鉴于您没有留下任何空白,仅保留第一个未分配位置的单个索引会更容易吗?

  5. 尽可能保持成员变量私有或受保护。在这种情况下,如果子类要扩展数组,那么它可能需要被保护。最好将其设为私有并在超类中有一个受保护的方法来扩展它。

  6. Arrays.copyOf 会为你做扩展

所以把所有这些放在一起:

class Fixed {
    private int size;
    private int[] store;
    private int index = 0;

    public Fixed(int size) {
        this.size = size;
        store = new int[size];
    }

    public void save(int value) throws ArrayStoreException {
        if (index == size)
            throw new ArrayStoreException();
        store[index++] = value;
    }

    protected void expand() {
        size *= 2;
        store = Arrays.copyOf(store, size);
    }
}

class Expandable extends Fixed {
    public void save(int value) {
        try {
            super.save(value);
        } catch (ArrayStoreException x) {
            expand();
            save(value);
        }
    }
}

如果您希望避免递归,那么您可以使用:

public void save(int value) {
    try {
        super.save(value);
    } catch (ArrayStoreException x) {
        expand();
        try {
            super.save(value);
        } catch (ArrayStoreException x) {
            throw new IllegalStateException("Cannot save after expansion");
        }
    }
}

【讨论】:

  • 感谢您的帮助。我不明白你第二点的后半部分“它需要调用超类的保存方法”。这是什么意思,或者我为什么要这样做?
  • 我们继承父类X的save方法,为什么要调用超类的save?
  • @jdoe 我建议子类应该覆盖save 的行为。如果您查看我的示例代码,您会发现它同时调用了它的超类save 和它自己的save。如果您出于某种原因明确需要创建一个新的save2 方法,那么您只需调用save 即可调用超类方法。
  • 最后一个问题:在你的代码中,为什么你用 super 调用方法 save 而在 catch 块中却没有?有什么区别?
  • @jdoe super.save 调用超类的save 方法。如果抛出异常,那么它会调用expand,然后调用自身。第二个save 不能调用超类的save,因为它需要处理异常(尽管我们知道此时它不会真正发生,因为您已经扩展了数组)。跨度>
【解决方案2】:

您可以将代码放在 finally 块中。 不管有没有异常,finally 块都会执行。 (例外:如果在 try 块中调用 System.exit(0);。)

从概念上讲,让我们开始

尝试阻止 - 您将代码放在您认为可能存在 ArrayStoreException 的地方。

Catch 块 - 此块仅在 try 块抛出任何异常时运行。 你把代码,它应该如何处理。根据要求,您可以向控制台抛出一条消息,告诉您错误的详细信息,如您的情况 ArrayStoreException 消息,并可以提示用户您将 ArrayList 的容量翻倍,因此可以编写代码以增加数组列表

Finally Block - 无论是否抛出任何异常,此块都会运行。您也可以在此处编写增加 ArrayList 大小的代码。但是,即使没有 ArrayStoreException 并且 ArrayList 有容量,它也会运行。

注意:如果代码抛出异常,并且没有处理或声明,那么代码将停止运行,不再运行任何代码。但是,如果错误处理得当,其余代码就会运行。

对于您的情况,我绝对建议您利用 try-catch-finally 块并将代码加倍大小的代码放在 catch 块中。

【讨论】:

    猜你喜欢
    • 2021-11-15
    • 2012-12-15
    • 1970-01-01
    • 2014-02-27
    • 2017-04-05
    • 2015-12-04
    • 1970-01-01
    • 1970-01-01
    • 2023-03-23
    相关资源
    最近更新 更多