主要内容

本页采用了机器翻译。点击此处可查看最新英文版本。

错误处理

错误概述

执行 MATLAB® 函数或数据转换期间发生的错误由标准 Java® 异常发出信号。这包括 MATLAB Runtime 错误以及 MATLAB 代码中的错误。

处理已检查异常

必须使用 throws 子句将检查异常声明为由方法抛出。MATLAB MATLABCompiler SDK™ Java 包支持 com.mathworks.toolbox.javabuilder 异常 MWException。此异常类继承自 java.lang.Exception,由每个 MATLAB Compiler SDK 生成的 Java 方法抛出,以表示调用期间发生了错误。所有正常的 MATLAB Runtime 错误以及用户创建的错误(例如,MATLAB 代码中的调用错误)都表现为 MWException

每个 Java 函数的 MATLAB 接口都使用 MWException 子句声明自己抛出 throws。例如,前面显示的 myprimes MATLAB 函数具有以下接口:

/* mlx interface - List version */
public void myprimes(List lhs, List rhs) throws MWException
{
    (implementation omitted)
}
/* mlx interface - Array version */
public void myprimes(Object[] lhs, Object[] rhs) 
                               throws MWException
{
    (implementation omitted)
 }
/* Standard interface - no inputs*/
public Object[] myprimes(int nargout) throws MWException
   {
      (implementation omitted)
   }
/* Standard interface - one input*/
public Object[] myprimes(int nargout, Object n) 
                                     throws MWException
   {
      (implementation omitted)
   }

任何调用 myprimes 的方法都必须执行以下两项操作之一:

  • 捕获并处理 MWException

  • 允许调用程序捕获它。

以下两节分别提供了示例。

处理被调用函数中的异常

此处显示的 getprimes 示例使用了其中的第一个方法。此方法本身处理异常,不需要在开始时包含 throws 子句。

public double[] getprimes(int n)
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, Double.valueOf((double)n));
      return (double[])((MWArray)y[0]).getData();
   }

   /* Catches the exception thrown by myprimes */
   catch (MWException e)
   {
      System.out.println("Exception: " + e.toString());
      return new double[0];
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

请注意,在这种情况下,如果出现错误,程序员有责任从方法中返回合理的内容。

示例中的 finally 子句包含在 try 模块中的所有其他处理执行完之后执行的代码。无论是否发生异常或执行 returnbreak 等控制流语句,此代码都会执行。通常的做法是把在离开函数之前必须执行的任何清理代码包含在 finally 模块中。文档示例在所有代码示例中使用 finally 模块来释放在方法中分配的本机资源。

有关释放资源的详细信息,请参阅在 JVM 中管理 MATLAB 资源

处理调用函数中的异常

在下一个示例中,调用 myprimes 的方法声明它抛出一个 MWException

public double[] getprimes(int n) throws MWException
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, Double.valueOf((double)n));
      return (double[])((MWArray)y[0]).getData();
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
      cls.dispose();
   }
}

处理未经检查的异常

执行过程中还可能发生几种类型的未经检查的异常。未经检查的异常是不需要使用 throws 子句明确声明的 Java 异常。MWArray API 类全部会抛出未经检查的异常。

MWArray 及其子类抛出的所有未经检查的异常都是 java.lang.RuntimeException 的子类。MWArray 可能引发以下异常:

  • java.lang.RuntimeException

  • java.lang.ArrayStoreException

  • java.lang.NullPointerException

  • java.lang.IndexOutOfBoundsException

  • java.lang.NegativeArraySizeException

此列表代表最有可能的例外情况。将来可能会添加其他内容。

捕获一般异常

您可以轻松重写 getprimes 示例来捕获方法调用和数据转换期间可能发生的任何异常。只需改变 catch 子句来捕获一般的 java.lang.Exception

public double[] getprimes(int n)
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, Double.valueOf((double)n));
      return (double[])((MWArray)y[0]).getData();
   }

   /* Catches the exception thrown by anyone */
   catch (Exception e)
   {
      System.out.println("Exception: " + e.toString());
      return new double[0];
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

捕获多种异常类型

此示例的第二个且更通用的变体通过引入两个 catch 子句来区分在编译方法调用中生成的异常和所有其他异常类型,如下所示:

public double[] getprimes(int n)
{
   myclass cls = null;
   Object[] y = null;

   try
   {
      cls = new myclass();
      y = cls.myprimes(1, Double.valueOf((double)n));
      return (double[])((MWArray)y[0]).getData();
   }

   /* Catches the exception thrown by myprimes */
   catch (MWException e)
   {
      System.out.println("Exception in MATLAB call: " +
         e.toString());
      return new double[0];
   }

   /* Catches all other exceptions */
   catch (Exception e)
   {
      System.out.println("Exception: " + e.toString());
      return new double[0];
   }

   finally
   {
      MWArray.disposeArray(y);
      if (cls != null)
         cls.dispose();
   }
}

此处 catch 子句的顺序很重要。因为 MWExceptionException 的子类,所以 catchMWException 子句必须出现在 catchException 子句之前。如果顺序相反,MWException catch 子句就永远不会执行。

使用 System.exit 的替代方法

任何使用通过 MATLAB Compiler SDK 生成的类的 Java 应用程序都应避免直接或间接调用 System.exit

任何直接或间接调用 System.exit 都将导致 JVM 以异常方式关闭。这可能会导致系统死锁。

使用 System.exit 也会导致 java 进程不可预测地退出。

使用 Swing 组件的 Java 程序最有可能调用 System.exit。以下是一些避免这种情况的方法:

  • 使用 public 接口 WindowConstants.DISPOSE_ON_CLOSE 方法作为 WindowConstants.EXIT_ON_CLOSE 的替代,作为 JFramesetDefaultCloseOperation 方法的输入。

  • 如果您想在 GUI 中提供一个退出按钮来终止应用程序,请不要在按钮的 System.exit 中调用 ActionListener,而是调用 dispose 上的 JFrame 方法。