c new 之前加括号HashMap(5)括号里的5是什么意识

Java常见错误列表 - ImportNew
| 分类: ,
Java常见错误列表:
遇见过上面没有列举的错误?如果有,那就在上提问吧,要在错误专栏(error folder)下吆。
1. 找不到符号(symbol)
当你在代码中引用一个没有声明的变量时一般会报这个错误。考虑下面的例子:
public class Test {
public static void main(String[] args) {
int a = 3;
int b = 4;
int c = 20;
average = (a + b + c)/5.0;
System.out.println(average);
1 error found:
File: Test.java
Error: Test.java:7: cannot find symbol
: variable average
location: class Test
在上面的例子中,变量average没有被声明——也就是说你需要告诉编译器average的类型是什么,例如:
double average = (a + b + c)/5.0;
此外,当你在代码中引用一个方法但没有在方法名后加上括号时也会报这个错误,加上括号用以表明引用的是个函数,即使当函数没有参数时也不能省略括号。例如:
public class Test {
public static void main(String[] args) {
public static void my_method() {
System.out.println(&Hello, world!&);
1 error found:
File: Test.java
Error: Test.java:7: cannot find symbol
: variable my_method
location: class Test
在上面的例子中,编译器在main方法中查找名为my_method的变量,实际上,你是想调用一个叫做my_method的方法:
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
第三种情况,如果你忘记导入你所使用的包时也会出现这个错误。例如,考虑下面这个从用户那里读入一个整数的例子:
public class Test {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
int n = console.nextInt();
2 errors found:
File: Test.java
Error: cannot find symbol
class Scanner
location: class Test
File: Test.java
Error: cannot find symbol
class Scanner
location: class Test
这里的问题是程序必须导入java.util.Scanner(或者java.util.)。否则,编译器不知道Scanner是什么类型。当你在处理文件的输入/输出时,如果忘记导入java.util.Arrays或者java.io.,也会遇到这个错误。
import java.util.*; // or --& import java.util.S
public class Test {
public static void main(String[] args) {
Scanner console = new Scanner(System.in);
int n = console.nextInt();
最后,当我们在使用大小敏感的变量名时也会遇到这个错误。Java中所有的标识符(identifiers)都是区分大小写的。这就意味着,如果我们声明了一个名为average的变量,然后在后面用Average引用它时,编译器就会报找不到Average这个变量的错误。
2. 类X是public的,应该被声明在名为X.java的文件中
在一个Java程序中,如果类名与文件名不匹配时会报这个错。例如,下面这个Foo.java程序:
public class Bar {
public static void main(String[] args) {
System.out.println(&Hello, world!&);
1 error found:
File: Foo.java
Error: class Bar is public, should be declared in a file named Bar.java
由于Foo与Bar不匹配,这段代码会编译失败。修改这个错误,我们既可以修改类名,也可以修改文件名。
3. 缺失类、接口或枚举类型
这个错误是一种与大括号有关的错误,一般来说,这个错误发生在程序最后有太多大括号时;例如:
public class Test {
public static void main(String[] args) {
System.out.println(&Hello!&);
1 error found:
File: Test.java
Error: class, interface, or enum expected
一种找出这种错误的方式是正确的缩进代码(因为这种错误总是与大括号有关)。我们可以在Dr.java中按组合键CTRL-A(去选中这个程序),然后按TAB键(来正确地缩减代码)。在我们上面的实例代码中,程序的最后有两个大括号,这在一个合法的程序中是不可能出现的。因此,我们仅仅去掉一个大括号就能够让程序正确的编译。
public class Test {
public static void main(String[] args) {
System.out.println(&Hello!&);
当编译器检查到代码中缺失字符时会出现”缺失X”这种形式的错误,错误信息会告诉你在哪行缺失了哪个字符,考虑下面的程序:
public class Test
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&)
2 errors found:
File: Test.java
Error: Test.java:1: '{' expected
File:.java
Error: Test.java:7: ';' expected
这个错误信息告诉你在第1行缺失了一个大括号,在第7行缺失了一个分号。解决这种错误很简单——只需把缺失的字符在正确的位置上补上即可。
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
5. 缺失标识符
当把代码写在了方法外时会出现这个错误;这种错误一般也是由大括号引起的。考虑下面的例子:
public class Test {
System.out.println(&Hello!&);
public static void main(String[] args) {
System.out.println(&World!&);
2 errors found:
File: Test.java
Error: &identifier& expected
File: Test.java
Error: illegal start of type
在这种情况下,很明显第一个打印语句应该放在main方法里面,这样才能通过编译。然而,当我们的程序中有多于一个方法并且大括号也不匹配时,这种“缺失标识符”的错误就不容易被发现了:
public class Test {
public static void main(String[] args) {
System.out.println(&Hello!&);}
System.out.println(&World!&);
3 errors found:
File: Test.java
Error: &identifier& expected
File: Test.java
Error: illegal start of type
File: Test.java
Error: class, interface, or enum expected
在上面的代码中多了一个大括号,但是因为代码没有正确的缩进,所以很难找出这个错误。这样使得main方法在打印“hello”语句后就结束了,这样打印“world”的语句就变成方法以外的代码了。修改这个错误的方式十分简单——只需要把第三行的大括号删除就可以了:
public class Test {
public static void main(String[] args) {
System.out.println(&Hello!&);
System.out.println(&World!&);
6. 非法的表达式开头
当编译器遇到一条不合法的语句时会报“非法的表达式开头”这种错误。考虑下面的例子:
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
5 errors found:
File: Test.java
Error: Test.java:6: illegal start of expression
File: Test.java
Error: Test.java:6: illegal start of expression
File: Test.java
Error: Test.java:6: ';' expected
File: Test.java
Error: Test.java:6: ';' expected
File: Test.java
Error: Test.java:9: reached end of file while parsing
这里,缺少了一个关闭main方法大括号。由于main方法没有被关闭,编译器把调用my_method方法之后的代码也当作main方法的一部分。然而,后面的代码是public static void my_method() {,很显然,这在一个方法内不合法。
“非法的表达式开头”这种错误不如我们上面提到的“××缺失”这种信息有帮助。对于这种错误(以及很多其他一些错误),非常有必要检查一下出错代码前面的那几行。对于上面那个例子,我们只需要在编译器报错的那行前面加上大括号关闭main方法就可以了。重新编译,所有的错误都解决了。
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
7. 类型不兼容
当你的程序在处理类型相关的问题时会报这个错。我们可以对一些类型进行相互转化,例如,你可以轻松把一个char类型转为int类型,反之亦然;你也可以通过向上转型把一个double类型转为int类型。但是,你不能把基本类型与像String这样的对象进行相互转换。例如:
public class Test {
public static void main(String[] args) {
int num = &Hello, world!&;
1 error found:
File: Test.java
Error: Test.java:3: incompatible types
: java.lang.String
required: int
一般来说,你不能像解决其他一些错误一样解决这种错误。这不是一种语法错误,而是一种关于类型的逻辑错误。把一个String类型转为int类型一般来说都是毫无意义。但是,在一些应用中,你可能需要把String类型转为int类型,比如,当这个字符串代码一个数字时:
public class Test {
public static void main(String[] args) {
int num = &500&;
1 error found:
File: Test.java
Error: Test.java:3: incompatible types
: java.lang.String
required: int
解决这种错误一般采用这样的方法:借助于Java中像Integer这样的类,这些基本类型的包装类中有能接受字符串类型的参数的方法,这样就把字符串类型转为整型了:
public class Test {
public static void main(String[] args) {
int num = Integer.parseInt(&500&);
但是,这种解决“类型不兼容”错误的方案是一种例外,不是什么规则,因为这种错误一般来自于逻辑上的错误。
&a name=&invalid-method&/&&/a&
### 8. 非法的方法声明;需要返回类型
在Java中的每个方法都要求明确的声明返回类型,即使这个方法什么也不返回,也要用void进行标识,就像main方法那样。
当一个方法没有声明返回类型时,会出现这种错误:
&pre class=&brush: gutter: first-line: 1; highlight: []; html-script: false&&
public class Test {
public static void main(String[] args) {
int x = getValue();
System.out.println(x);
public static getValue() {
return 10;
1 error found:
File: Test.java
Error: Test.java:7: invali return type required
解决这种问题,在方法声明处加上合适的返回类型即可:
public class Test {
public static void main(String[] args) {
int x = getValue();
System.out.println(x);
public static int getValue() {
return 10;
9. 数组越界(java.lang.ArrayIndexOutOfBoundsException)
当你使用不合法的索引访问数组时会报数组越界这种错误,数组arr的合法错误范围是[0, arr.length-1];当你访问这之外的索引时会报这个错。例如:
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
for (int i = 0; i &= arr. i++) {
System.out.println(arr[i]);
java.lang.ArrayIndexOutOfBoundsException: 3
at Test.main(Test.java:5)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at edu.rice.cs.piler.JavacCompiler.runCommand(JavacCompiler.java:272)
这种错误很像我们下面即将说的,这种错误的错误信息后面部分与错误不大相关。但是,第1行就告诉我们错误的原因是数组越界了,在我们上面的例子,非法的索引值是3,下面一行的错误信息告诉你错误发生在Test类的第5行上,在main方法之内。
在上面的例子中,因为我们循环过多导致出现这个错误,循环索引i最大可以为4,而4超过了数组的长度,因此越界了。相反,i的上界应该使用&或者相同效果的语句来界定。
public class Test {
public static void main(String[] args) {
int[] arr = {1, 2, 3};
for (int i = 0; i & arr. i++) {
System.out.println(arr[i]);
当处理数组越界时,打印出遍历数组的索引十分有帮助,这样我们就能够跟踪代码找到为什么索引达到了一个非法的值。
10. 字符串索引越界(java.lang.StringIndexOutOfBoundsException)
当你在程序中去访问一个字符串的非法索引时会报字符串索引越界这个错误。一个String的合法索引范围是[0,str.leng()-1];当你访问这之外的索引时会报这个错。例如:
public class Test {
public static void main(String[] args) {
String str = &Hello, world!&;
String a = str.substring(-1, 3);
String b = str.charAt(str.length());
String c = str.substring(0, 20);
java.lang.StringIndexOutOfBoundsException: String index out of range: -1
at java.lang.String.substring(Unknown Source)
at Test.main(Test.java:5)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at edu.rice.cs.piler.JavacCompiler.runCommand(JavacCompiler.java:271)
这种错误的错误信息后面部分与错误不大相关。但是,第1行就说明了错误的地方是字符串的索引,在我们这个例子,非法的索引是-1,下面一行错误信息告诉我们这个错误是在执行substring方法时抛出的,发生错误的位置是Test类的第5行。这种与错误相关的程序轨迹告诉我们程序是在调用哪个方式时出的错,这样我们就能追踪代码,并最终改正它。
值得注意的是,上面程序中的a,b,c都会抛出这种错误,但是程序在遇到第一个错误时就被迫终止了。
这不是编译时的错误,而是运行时的错误。换句话说,编译器能正确编译这段程序因为它只是在逻辑上有错,此外,在程序运行之前,我们也没法预料是否会有错误发生。解决这种错误,我们需要改正程序的逻辑来保证没有地方访问非法的索引。
11. 类Y中的方法X参数不匹配
当你在调用函数时参数数量或顺序不对时会报这个错误。例如,考虑下面的程序:
public class Test {
public static void main(String[] args) {
myMethod(1.0, 2, &Hello!&);
public static void myMethod(double d, String s, int x) {
System.out.println(s + & & + d + & & + x);
1 error found:
File: Test.java
Error: method myMethod in class Test cannot be ap
required: double,java.lang.String,int
found: double,int,java.lang.String
reason: actual argument int cannot be converted to java.lang.String by method invocation conversion
这种错误的错误信息非常有帮助。“required”这一行错误信息告诉我们方法的参数是什么,方法的参数列表在这后面。在上面的例子中,myMethod方法的参数先后顺序应该是double类型、String类型,最后是一个int类型的变量。
错误信息的下一行(found开头的这一行)告诉我们程序在调用这个方法时用了什么样的参数。在上面的例子中,是一个double类型,一个int类型,最后是一个String类型的变量,很显然顺序是不对的。
解决这种错误,我们需要保证方法的参数个数和类型与函数声明时都一致才行。
public class Test {
public static void main(String[] args) {
myMethod(1.0, &Hello!&, 2);
public static void myMethod(double d, String s, int x) {
System.out.println(s + & & + d + & & + x);
12. 缺少return语句
当你声明一个方法有返回值但是没有写return语句时会报这个错误。例如:
public class Test {
public static void main(String[] args) {
int x = twice(5);
System.out.println(x);
public static int twice(int x) {
int value = 2 *
1 error found:
File: Test.java
Error: Test.java:9: missing return statement
我们通过函数声明告知编译器twice方法会返回一个int值,但是我们没有写return语句:
public class Test {
public static void main(String[] args) {
int x = twice(5);
System.out.println(x);
public static int twice(int x) {
int value = 2 *
在某些if条件句中,编译器也会认为函数没有返回值。像下面这个例子:
public class Test {
public static void main(String[] args) {
int x = absVal(-5);
System.out.println(x);
public static int absVal(int x) {
if (x & 0) {
return -x;
if (x &= 0) {
1 error found:
File: Test.java
[line: 15]
Error: Test.java:15: missing return statement
避免这种错误,我们可以选择使用else语句(就像我们在一样),或者我们可以不用第二个if语句,因为我们知道,如果程序能够执行到这个地方,程序就可以直接返回x了:
public class Test {
public static void main(String[] args) {
int x = absVal(-5);
System.out.println(x);
public static int absVal(int x) {
if (x & 0) {
return -x;
13. 精度损失
当你把信息保存到一个变量中,而信息量超过了这个变量的所能容纳的能力时会报这个错。最常见的例子是把double类型赋值给int类型。
public class Test {
public static void main(String[] args) {
int pi = 3.14159;
System.out.println(&The value of pi is: & + pi);
1 error found:
File: Test.java
Error: Test.java:3: possible loss of precision
required: int
这个错误发生的原因是计算机在存储double类型时所需的空间是int类型的两倍。如果你不在乎精度的损失,你可以通过上转型的方法来告知编译器:
public class Test {
public static void main(String[] args) {
int pi = (int)3.14159;
System.out.println(&The value of pi is: & + pi);
现在编译器不会报错了,但是pi这个变量由于进行了取整,最终值为3。
14. 在解析时到达了文件结尾
当你没有用大括号关闭你的程序时会出现这个错误。错误信息明确的指出编译器在没有明确程序该结束时就到达了文件的结尾。例如:
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
1 error found:
File: Test.java
Error: Test.java:9: reached end of file while parsing
解决这个错误,我们只需要在最后加上关闭程序的大括号(“}”)即可。有时仅仅在文件末尾缺少了一个大括号,但也有可能是在程序的中间少写或多写了大括号的缘故。
一种调试的方法是用快捷键CTRL-A + TAB来正确的缩减你的代码。由于程序的问题与大括号有关,这样代码就不能够正确的缩进。找到程序中第一个缩进不正确的地方,这就是错误产生的地方。
一旦大括号正确的匹配上,编译器就不会报错了:
public class Test {
public static void main(String[] args) {
my_method();
public static void my_method() {
System.out.println(&Hello, world!&);
15. 执行不到的语句
当编译器检测到某些语句在整个程序流程中不可能被执行到时会报这个错。这个错误经常是由return或break后的语句所导致的。例如:
public class Test {
public static void main(String[] args) {
int value = twice(5);
System.out.println(value);
public static int twice(int x) {
int twice = 2 *
System.out.println(&Returning & + twice);
2 errors found:
File: Test.java
[line: 10]
Error: Test.java:10: unreachable statement
File: Test.java
[line: 11]
Error: Test.java:11: missing return statement
编译器报了两个错:一个是说System.out.println(“Returning ” + twice);这一行不可能被法执行到,另一个错误是因为编译器假设可以执行print语句,这样的话我们在它之后也应该有个return语句,但是程序中没有,所以报这个错。
解决这个错误,我们可以把print语句放到return的前面,这样程序就能执行了:
public class Test {
public static void main(String[] args) {
int value = twice(5);
System.out.println(value);
public static int twice(int x) {
int twice = 2 *
System.out.println(&Returning & + twice);
15. 变量没被初始化
当你在程序中去引用一个没有被初始化的变量时会报这个错。下面看一个非常简单的例子:
public class Test {
public static void main(String[] args) {
int x = 2;
System.out.println(x + y);
1 error found:
File: Test.java
Error: Test.java:5: variable y might not have been initialized
在程序中你没有告知编译器y的值,所以y不能被打印,y需要像x一样被初始化以后才能使用。
在一些更复杂的情形下,if语句可能导致变量没有被初始化。例如:
public class Test {
public static void main(String[] args) {
boolean setX =
if (setX) {
System.out.println(x);
1 error found:
File: Test.java
Error: Test.java:8: variable x might not have been initialized
这里很明显,x将不能被正确的初始化,因此编译器报错。但是,在一些情况下虽然我们能够很清楚的知道变量能够被初始化,但是编译器不能和我们一样推测出变量是否会被初始化,例如:
public class Test {
public static void main(String[] args) {
boolean setToTen =
if (setToTen) {
if (!setToTen) {
System.out.println(x);
1 error found:
File: Test.java
[line: 14]
Error: Test.java:14: variable x might not have been initialized
很明显,x一定会被两个if语句中的任意一个赋值,但是编译器并不能推测出(译者注:需要在运行时才能知道),一种修改这个错误的方式是使用else语句。当使用else语句时,编译器就有最够的证据推测出x将被初始化:
public class Test {
public static void main(String[] args) {
boolean setToTen =
if (setToTen) {
System.out.println(x);
原文链接:
- 译文链接: [ 转载请保留原文出处、译者和译文链接。]
关于作者:
新浪微博: 个人技术博客:
可能感兴趣的文章
我是没觉得你这样改让代码变得优雅了
花溪的小石头
关于ImportNew
ImportNew 专注于 Java 技术分享。于日 11:11正式上线。是的,这是一个很特别的时刻 :)
ImportNew 由两个 Java 关键字 import 和 new 组成,意指:Java 开发者学习新知识的网站。 import 可认为是学习和吸收, new 则可认为是新知识、新技术圈子和新朋友……
新浪微博:
推荐微信号
反馈建议:@
广告与商务合作QQ:
– 好的话题、有启发的回复、值得信赖的圈子
– 写了文章?看干货?去头条!
– 为IT单身男女服务的征婚传播平台
– 优秀的工具资源导航
– 活跃 & 专业的翻译小组
– 国内外的精选博客文章
– UI,网页,交互和用户体验
– JavaScript, HTML5, CSS
– 专注Android技术分享
– 专注iOS技术分享
– 专注Java技术分享
– 专注Python技术分享
& 2017 ImportNew2014年7月 Java大版内专家分月排行榜第二
2015年1月 Java大版内专家分月排行榜第三2014年8月 Java大版内专家分月排行榜第三
2014年7月 Java大版内专家分月排行榜第二
2015年1月 Java大版内专家分月排行榜第三2014年8月 Java大版内专家分月排行榜第三
2014年7月 Java大版内专家分月排行榜第二
2015年1月 Java大版内专家分月排行榜第三2014年8月 Java大版内专家分月排行榜第三
2014年5月 Java大版内专家分月排行榜第三
2016年1月 Java大版内专家分月排行榜第二2015年12月 Java大版内专家分月排行榜第二2015年8月 Java大版内专家分月排行榜第二2015年3月 Java大版内专家分月排行榜第二2015年1月 Java大版内专家分月排行榜第二2014年12月 Java大版内专家分月排行榜第二2014年11月 Java大版内专家分月排行榜第二2014年6月 Java大版内专家分月排行榜第二2014年4月 Java大版内专家分月排行榜第二2014年1月 Java大版内专家分月排行榜第二2013年11月 Java大版内专家分月排行榜第二
2015年9月 Java大版内专家分月排行榜第三2015年6月 Java大版内专家分月排行榜第三2015年5月 Java大版内专家分月排行榜第三2015年2月 Java大版内专家分月排行榜第三2014年3月 Java大版内专家分月排行榜第三2013年12月 Java大版内专家分月排行榜第三
本帖子已过去太久远了,不再提供回复功能。Java map双括号初始化方式的问题_Linux编程_Linux公社-Linux系统门户网站
你好,游客
Java map双括号初始化方式的问题
来源:Linux社区&
作者:liubo2012
关于Java双括号的初始化凡是确实很方便,特别是在常量文件中,无可替代。如下所示:
Map map = new HashMap() {   {   put("Name", "Unmi");   put("QQ", "1125535");   } };
好处很明显就是一目了然。这里来罗列下此种方法的坏处,如果这个对象要串行化,可能会导致串行化失败。
1.此种方式是匿名内部类的声明方式(不懂的下文有详尽解释),所以引用中持有着外部类的引用。所以当时串行化这个集合时外部类也会被不知不觉的串行化,当外部类没有实现serialize接口时,就会报错。
2.上例中,其实是声明了一个继承自Hashset的子类。然而有些串行化方法,例如要通过Gson串行化为json,或者要串行化为xml时,类库中提供的方式,是无法串行化Hashset或者HashMap的子类的,从而导致串行化失败。解决办法:重新初始化为一个Hashset对象:
new HashMap(map);
这样就可以正常初始化了。
双括号写法的原理:
第一层括弧 实际是定义了一个内部匿名类 (Anonymous Inner Class),第二层括弧 实际上是一个实例初始化块 (instance initializer block),这个块在内部匿名类构造时被执行。这个块之所以被叫做&实例初始化块&是因为它们被定义在了一个类的实例范围内。
上面代码如果是写在 TestDoubleBrace 类中,编译后你会看到会生成 TestDoubleBrace$1.class 文件,反编译该文件内容是:
final class com.unmi.TestDoubleBrace$1 extends java.util.HashMap{ //创建了一个 HashMap 的子类 TestDoubleBracke$1
  com.unmi.TestDoubleBrace$1();
Code:   0: aload_0   1: invokespecial #8; //Method java/util/HashMap."":()V //{} 中的代码放到了构造方法中去了   4: aload_0   5: ldc #10; //String Name   7: ldc #12; //String Unmi   9: invokevirtual #14; //Method put:(Ljava/lang/OLjava/lang/O)Ljava/lang/O   12: pop   13: aload_0   14: ldc #18; //String QQ   16: ldc #20; //String 1125535   18: invokevirtual #14; //Method put:(Ljava/lang/OLjava/lang/O)Ljava/lang/O   21: pop   22: return }
编写高质量代码 改善Java程序的151个建议 PDF高清完整版
Java 8简明教程
Java对象初始化顺序的简单验证
Java对象值传递和对象传递的总结
Java对象序列化ObjectOutputStream和ObjectInputStream示例
本文永久更新链接地址:
相关资讯 & & &
& (10/04/:58)
& (08/01/:07)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款

我要回帖

更多关于 java new 大括号 的文章

 

随机推荐