Java如何处理除零?

mrp*_*pyo 18 java divide-by-zero

它是否只是在每次完成除法时检查除数是否与零不同(即使在JIT编码中)?

我的意思是VM如何在不被操作系统杀死的情况下设法抛出异常?

BRP*_*ock 32

在Unix环境中,在其中通过零分区signal引导SIGFPE,JVM将安装一个信号处理程序,该信号处理程序捕获SIGFPE并依次为throws ArithmeticException.如果您对内部感兴趣,请参阅例如man signal

我认为OP所要求的是基于以下事实:除非SIGFPE处理程序到位,否则大多数进程将在接收此信号时采取默认操作,即终止.因此,例如C程序

 int main (int argc, char** argv) { int n = 5 / 0; } 
Run Code Online (Sandbox Code Playgroud)

...如果它甚至编译,将被默认SIGFPESIG_DFL动作杀死.相反,JVM的处理程序发出(catch能够),RuntimeException以便可以以本机看似的方式处理这些异常.

正如其他几个人所指出的那样,只是为了完整性,实际上SIGFPE从内核生成的内容通常是从处理器本身的特殊中断映射出来的; 因此,"管道"就像

  • CPU错误陷阱中断→内核中断处理程序SIGFPE SIG_DFL→→处理死亡

要么

  • CPU错误陷阱中断→内核中断处理程序→ SIGFPEJVM中的处理程序→ RuntimeException ArithmeticException用户代码

在非Unix平台上,处理是类似的.


64B*_*Bob 7

Java像任何其他语言一样处理这种情况.除以零错误会产生处理器异常,从而触发中断.操作系统"读取"中断,并在注册处理程序时将其转发给程序.由于Java注册了一个处理程序,它会收到错误,然后将其转换为一个ArithmeticException向上移动的堆栈.


Eri*_*ski 6

JVM使用C来捕获除以零的分区:

#include <stdio.h>
#include <signal.h>
#include <stdlib.h>

void fpe_handler(int signum) {
      printf("signal is %d", signum);
      printf("JVM throws an ArithmeticException here...\n");
      exit (1);
}

int main() {
      int a = 5;
      int b = 0;
      signal(SIGFPE, fpe_handler);   
      printf("%d\n", a / b); 
      return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译并运行它打印:

el@apollo:~$ gcc -o catch_sigfpe myc.c

el@apollo:~$ ./catch_sigfpe
signal is 8
JVM throws an ArithmeticException here...

el@apollo:~$
Run Code Online (Sandbox Code Playgroud)

操作系统同步引发SIGFPE异常,C程序捕获它,然后java构造并向您提供ArithmeticException并在其自身之后进行清理以停止Java程序.

有关此处返回的信号的更多信息,请访问:http: //publib.boulder.ibm.com/infocenter/javasdk/v6r0/index.jsp?topic =%2Fcom.ibm.java.doc.user.aix64.60%2Fuser%2Fsighand html的