首页 \ 问答 \ Java异常和Catch子句(Java Exceptions and Catch Clause)

Java异常和Catch子句(Java Exceptions and Catch Clause)

这是我为测试编写的一些简单代码。
我知道我无法定义一个catch块来捕获一个检查异常,即try块中的代码没有声明要抛出(因为它包含无法访问的语句而编译器不会让我)。

那么,这里到底发生了什么? (java.io.InvalidClassException是Exception的子类,因此它是一个经过检查的异常。)

import java.util.*;
import java.io.*;

class Test {

  public void copy()  {
    try (InputStream is=new FileInputStream("file1");
         OutputStream os=new FileOutputStream("file2");) {
      byte[] buffer=new byte[1024];
      int bytesRead=0;
      while ((bytesRead=is.read(buffer)) != -1) {
        os.write(buffer,0,bytesRead);
      }
    }
    catch (java.io.InvalidClassException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

}

代码编译得很好......怎么可能?


Here is some simple code I was writing for a test.
I know that I can't define a catch block that catches a checked exception that the code in the try block doesn't declare to throw (because it would contain unreachable statements and the compiler won't let me).

So, what is happening here exactly? (java.io.InvalidClassException is a subclass of Exception and so it's a checked exception.)

import java.util.*;
import java.io.*;

class Test {

  public void copy()  {
    try (InputStream is=new FileInputStream("file1");
         OutputStream os=new FileOutputStream("file2");) {
      byte[] buffer=new byte[1024];
      int bytesRead=0;
      while ((bytesRead=is.read(buffer)) != -1) {
        os.write(buffer,0,bytesRead);
      }
    }
    catch (java.io.InvalidClassException e) {
      e.printStackTrace();
    }
    catch (IOException e) {
      e.printStackTrace();
    }
  }

}

The code compiles fine... How is that possible??


原文:https://stackoverflow.com/questions/35088722
更新时间:2022-07-21 19:07

最满意答案

语言中需要在类型声明中的大括号后面的分号。 从最早的C版本开始就是这样

是的,人们确实做你刚才所说的声明。 在方法中创建作用域类型很有用。

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

在这种情况下,我认为很明显,为什么要使用分号。 至于为什么在头文件中声明更广泛的情况下,我不确定是需要的。 我的猜测是,它是历史性的,并且完成了使编写器更容易编写。


The semi-colon after the closing brace in a type declaration is required by the language. It's been that way since the earliest versions of C.

And yes, people do indeed do the declaration you just put up there. It's useful for creating scoped types inside of methods.

void Example() {
  struct { int x; } s1;
  s1.x = 42;

  struct ADifferentType { int x; };
}

In this case, I think it's clear why the semi-colons are needed. As to why it's needed in the more general case of declaring in the header file I'm unsure. My guess is that it's historical and was done to make writing the compiler easier.

相关问答

更多
  • “双曲花括号”中的内括号是初始化块。 (把它们当作构造函数。) { // class declaration { // initializer block ... } } 例如,请参阅什么是初始化块? 。 由于您不能直接在类声明中放置语句(“代码”),如下所示: new YourClass() { System.out.println("hello"); } 你会体验到“Eclipse让你使用双花括号”,因为以下几点 new Yo ...
  • 如果您需要查找所选择的支架,可以使用Ctrl + Shift + P。 另外请注意,您可以使用Ctrl + Shift + L查看所在编辑器的所有可用快捷键(并再次使用它来查看所有潜在键绑定的列表,以及在列表上进行筛选的功能并编辑快捷键)。 You can use Ctrl+Shift+P if you need to find the matching bracket of the selected one. Also note that you can use Ctrl+Shift+L to see a ...
  • 如果您对EOK的定义如下: #define EOK 0; 那么它会导致这种类型的错误,因为它在else达到之前强制终止if语句,使其成为一个没有匹配if的语句。 宏替换后,编译器会看到此代码: if(GetSomething()) error = 0;; else If your definition of EOK is as follows: #define EOK 0; then it would cause this type of error, because it forcibly te ...
  • 这是允许的,因为标准是这样说的:C99部分6.7.8,§14: 字符类型的数组可以由字符串文字初始化,可选地括在大括号中。 字符串文字的连续字符(包括终止空字符,如果有空格或数组未知大小)初始化数组的元素。 这意味着两者都是这样 char s[] = { "Hello World" }; 和 char s[] = "Hello World"; 只不过是语法糖 char s[] = { 'H', 'e', 'l', 'l', 'o', ' ', 'W', 'o', 'r', 'l', 'd', 0 }; ...
  • 在语句之后使用分号。 这是一个声明: var foo = function() { alert("bar"); }; 因为它是一个变量赋值(即为变量创建和分配一个匿名函数)。 不要说的两件事情就是函数声明: function foo() { alert("bar"); } 和块: { alert("foo"); } 注意:没有分号的相同块构造也适用于for , do和while循环。 You use a semicolon after a statement. This is a stat ...
  • 语言中需要在类型声明中的大括号后面的分号。 从最早的C版本开始就是这样 是的,人们确实做你刚才所说的声明。 在方法中创建作用域类型很有用。 void Example() { struct { int x; } s1; s1.x = 42; struct ADifferentType { int x; }; } 在这种情况下,我认为很明显,为什么要使用分号。 至于为什么在头文件中声明更广泛的情况下,我不确定是需要的。 我的猜测是,它是历史性的,并且完成了使编写器更容易编写。 The semi- ...
  • 下面的Lambda很好,没有大括号 是的,但是它是一个表达式lambda而不是语句lambda 。 从那些文档: 语句lambda类似于表达式lambda,除了语句用括号括起来 这是一个有点奇怪的问题,因为括号的使用使它成为一个声明lambda。 答案b肯定是正确的,因为它是唯一的错误断言:语句lambdas 可以返回值。 一个语句lambda肯定可以包含多个语句,并且肯定可以返回一个值,尽管它必须使用return语句来执行此操作: // Statement lambda with multiple sta ...
  • 看起来你似乎混合了两个概念:变量声明和变量赋值。 要在Swift中声明一个空数组,你必须明确指出数组可以容纳的类型。 您可以通过长期定义来做到这一点: var persons: Array 或简写语法(首选): var persons: [String] 请注意使用冒号“:”而不是等号“=”。 这两个都说“我声明存在一个名为'persons'的变量(不是常量),这个变量将是一个可变的数组,其中包含了所有的字符串,现在它还没有定义。 在Obj-C中,你可以将任何类型的对象放入NSArray ...
  • 此代码有效ES6 / ES2015,但无效ES5。 node.js> = 6.4支持解构分配。 如果您的Jasmine使用旧版本运行,则无法运行。 不确定Visual Studio,但看起来你需要最新版本的VS 2015才能拥有ES6功能。 因此,您应该更新工具,或者只配置Typescript,以便它以ES5为目标。 This code is valid ES6/ES2015, but is not valid ES5. Destructuring assignments are supported in ...
  • 我认为共识是使用大括号。 如果省略大括号,则可能会有人在没有注意到缺失大括号的情况下添加额外的行。 I think the consensus is to use braces. If you omit the braces there is a risk that someone will add an extra line without noticing the missing braces.

相关文章

更多

最新问答

更多
  • 您如何使用git diff文件,并将其应用于同一存储库的副本的本地分支?(How do you take a git diff file, and apply it to a local branch that is a copy of the same repository?)
  • 将长浮点值剪切为2个小数点并复制到字符数组(Cut Long Float Value to 2 decimal points and copy to Character Array)
  • OctoberCMS侧边栏不呈现(OctoberCMS Sidebar not rendering)
  • 页面加载后对象是否有资格进行垃圾回收?(Are objects eligible for garbage collection after the page loads?)
  • codeigniter中的语言不能按预期工作(language in codeigniter doesn' t work as expected)
  • 在计算机拍照在哪里进入
  • 使用cin.get()从c ++中的输入流中丢弃不需要的字符(Using cin.get() to discard unwanted characters from the input stream in c++)
  • No for循环将在for循环中运行。(No for loop will run inside for loop. Testing for primes)
  • 单页应用程序:页面重新加载(Single Page Application: page reload)
  • 在循环中选择具有相似模式的列名称(Selecting Column Name With Similar Pattern in a Loop)
  • System.StackOverflow错误(System.StackOverflow error)
  • KnockoutJS未在嵌套模板上应用beforeRemove和afterAdd(KnockoutJS not applying beforeRemove and afterAdd on nested templates)
  • 散列包括方法和/或嵌套属性(Hash include methods and/or nested attributes)
  • android - 如何避免使用Samsung RFS文件系统延迟/冻结?(android - how to avoid lag/freezes with Samsung RFS filesystem?)
  • TensorFlow:基于索引列表创建新张量(TensorFlow: Create a new tensor based on list of indices)
  • 企业安全培训的各项内容
  • 错误:RPC失败;(error: RPC failed; curl transfer closed with outstanding read data remaining)
  • C#类名中允许哪些字符?(What characters are allowed in C# class name?)
  • NumPy:将int64值存储在np.array中并使用dtype float64并将其转换回整数是否安全?(NumPy: Is it safe to store an int64 value in an np.array with dtype float64 and later convert it back to integer?)
  • 注销后如何隐藏导航portlet?(How to hide navigation portlet after logout?)
  • 将多个行和可变行移动到列(moving multiple and variable rows to columns)
  • 提交表单时忽略基础href,而不使用Javascript(ignore base href when submitting form, without using Javascript)
  • 对setOnInfoWindowClickListener的意图(Intent on setOnInfoWindowClickListener)
  • Angular $资源不会改变方法(Angular $resource doesn't change method)
  • 在Angular 5中不是一个函数(is not a function in Angular 5)
  • 如何配置Composite C1以将.m和桌面作为同一站点提供服务(How to configure Composite C1 to serve .m and desktop as the same site)
  • 不适用:悬停在悬停时:在元素之前[复制](Don't apply :hover when hovering on :before element [duplicate])
  • 常见的python rpc和cli接口(Common python rpc and cli interface)
  • Mysql DB单个字段匹配多个其他字段(Mysql DB single field matching to multiple other fields)
  • 产品页面上的Magento Up出售对齐问题(Magento Up sell alignment issue on the products page)