爪哇,400
Java很幸运(?)有许多Exception
s和Error
s。有许多Exception
特定于单个类的操作的。作为最极端情况之一的一个例子,有10 Exception
多个(都是的子类IllegalFormatException
)Formatter
仅用于类,而我已经花了一些时间(几乎)使所有代码都抛出。
我当前的答案有40个不同的Exception
s / Error
s,它们根据System.nanoTime()
某个整数的模数随机执行。
此方法只能用于测量经过时间,并且与系统或挂钟时间的任何其他概念无关。返回的值表示自某个固定但任意的原始时间以来的纳秒(也许是将来的时间,因此值可能为负)。在Java虚拟机的实例中,此方法的所有调用都使用相同的源。其他虚拟机实例可能使用其他来源。
应该允许上面的方法,因为它属于情况“ 3.不能使用tic或cpu周期的数量,除非它们相对于主程序线程的开始进行计数”。
编译指令
强烈建议您使用Oracle的JRE / JDK或OpenJDK来运行代码。否则,可能不会引发某些Exception,因为其中有些依赖于引用实现的内部细节,并且我没有可靠的后备。
以下代码可使用成功编译,javac 1.7.0_11
并在上产生所有异常java 1.7.0_51
。
要运行此代码,您需要将以下代码复制并粘贴到Unicode感知编辑器(例如Notepad ++)中,并将其保存为UTF-16(大字节序或小字节序无关紧要,只要编写BOM即可) 。
将工作目录(cd
)更改为保存源代码的位置(这很重要)。
使用以下命令编译代码:
javac G19115.java -encoding "UTF-16"
并运行代码:
java G19115
我的代码中没有破坏性的内容,因为我也想在计算机上对其进行测试。最“危险”的代码是删除ToBeRemoved.class
当前文件夹中的文件。除此之外,其余的都不会触及文件系统或网络。
import java.util.*;
import java.util.regex.*;
import java.lang.reflect.*;
import java.text.*;
import java.io.*;
import java.nio.*;
import java.nio.charset.*;
import java.security.*;
class G19115 {
// The documentation says System.nanoTime() does not return actual time, but a relative
// time to some fixed origin.
private static int n = (int) ((System.nanoTime() % 40) + 40) % 40;
@SuppressWarnings("deprecation")
public static void main(String args[]) {
/**
* If the code is stated to be a bug, then it is only guaranteed to throw Exception on
* Oracle's JVM (or OpenJDK). Even if you are running Oracle's JVM, there is no
* guarantee it will throw Exception in all future releases future either (since bugs
* might be fixed, classes might be reimplemented, and an asteroid might hit the earth,
* in order from the least likely to most likely).
*/
System.out.println(n);
switch (n) {
case 0:
// Bug JDK-7080302
// https://bugs.openjdk.java.net/browse/JDK-7080302
// PatternSyntaxException
System.out.println(Pattern.compile("a(\u0041\u0301\u0328)", Pattern.CANON_EQ));
System.out.println(Pattern.compile("öö", Pattern.CANON_EQ));
// Leave this boring pattern here just in case
System.out.println(Pattern.compile("??+*"));
break;
case 1:
// Bug JDK-6984178
// https://bugs.openjdk.java.net/browse/JDK-6984178
// StringIndexOutOfBoundsException
System.out.println(new String(new char[42]).matches("(?:(?=(\\2|^))(?=(\\2\\3|^.))(?=(\\1))\\2)+."));
// Leave this boring code here just in case
System.out.println("".charAt(1));
break;
case 2:
// IllegalArgumentException
// Bug JDK-8035975
// https://bugs.openjdk.java.net/browse/JDK-8035975
// Should throw IllegalArgumentException... by documentation, but does not!
System.out.println(Pattern.compile("pattern", 0xFFFFFFFF));
// One that actually throws IllegalArgumentException
System.out.println(new SimpleDateFormat("Nothing to see here"));
break;
case 3:
// Bug JDK-6337993 (and many others...)
// https://bugs.openjdk.java.net/browse/JDK-6337993
// StackOverflowError
StringBuffer buf = new StringBuffer(2000);
for (int i = 0; i < 1000; i++) {
buf.append("xy");
}
System.out.println(buf.toString().matches("(x|y)*"));
// Leave this boring code here just in case
main(args);
break;
case 4:
// NumberFormatException
String in4 = "123\r\n";
Matcher m4 = Pattern.compile("^\\d+$").matcher(in4);
if (m4.find()) {
System.out.println(Integer.parseInt(in4));
} else {
System.out.println("Bad input");
}
// NotABug(TM) StatusByDesign(TM)
// $ by default can match just before final trailing newline character in Java
// This is why matches() should be used, or we can call m.group() to get the string matched
break;
case 5:
// IllegalStateException
String in5 = "123 345 678 901";
Matcher m5 = Pattern.compile("\\d+").matcher(in5);
System.out.println(m5.group(0));
// The Matcher doesn't start matching the string by itself...
break;
case 6:
// ArrayIndexOutOfBoundsException
// Who is the culprit?
String[] in6 = {
"Nice weather today. Perfect for a stroll along the beach.",
" Mmmy keeyboaardd iisss bbrokkkkeeen ..",
"",
"\t\t\t \n\n"};
for (String s: in6) {
System.out.println("First token: " + s.split("\\s+")[0]);
}
// Culprit is "\t\t\t \n\n"
// String.split() returns array length 1 with empty string if input is empty string
// array length 0 if input is non-empty and all characters match the regex
break;
case 7:
// ConcurrentModificationException
List<Integer> l7 = testRandom(42);
Integer prev = null;
// Remove duplicate numbers from the list
for (Integer i7: l7) {
if (prev == null) {
prev = i7;
} else {
if (i7.equals(prev)) {
l7.remove(i7);
}
}
}
System.out.println(l7);
// This is one of the typical mistakes that Java newbies run into
break;
case 8:
// ArithmeticException
// Integer division by 0 seems to be the only way to trigger this exception?
System.out.println(0/0);
break;
case 9:
// ExceptionInInitializerError
// Thrown when there is an Exception raised during initialization of the class
// What Exception will be thrown here?
Static s9 = null;
System.out.println(s9.k);
// A bit less interesting
Static ss9 = new Static();
// ----
// A class is only initialized when any of its method/field is
// used for the first time (directly or indirectly)
// Below code won't throw Exception, since we never access its fields or methods
// Static s;
// OR
// Static s = null;
break;
case 10:
// BufferOverflowException
short s10 = 20000;
ShortBuffer b10 = ShortBuffer.allocate(0).put(s10);
// Boring stuff...
break;
case 11:
// BufferUnderflowException
ShortBuffer.allocate(0).get();
// Another boring stuff...
break;
case 12:
// InvalidMarkException
ShortBuffer.allocate(0).reset();
// Boring stuff again...
// reset() cannot be called if mark() is not called before
break;
case 13:
// IndexOutOfBoundsException
System.out.println("I lost $m dollars".replaceAll("[$]m\\b", "$2"));
// $ needs to be escaped in replacement string, since it is special
break;
case 14:
// ClassCastException
Class c14 = Character.class;
for (Field f: c14.getFields()) {
System.out.println(f);
try {
int o = (int) f.get(c14);
// If the result is of primitive type, it is boxed before returning
// Check implementation of sun.reflect.UnsafeStaticIntegerFieldAccessorImpl
System.out.println(o);
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
break;
case 15:
// NoSuchElementException
List<Integer> l15 = new ArrayList<Integer>();
Iterator i = l15.iterator();
System.out.println(i.next());
// Another boring one...
break;
case 16:
// ArrayStoreException
Object x[] = new String[3];
x[0] = new Integer(0);
// Straight from the documentation
// I don't even know that this exists...
break;
case 17:
// IllegalThreadStateException
Thread t17 = new Thread();
t17.start();
t17.setDaemon(true);
// setDaemon can only be called when the thread has not started or has died
break;
case 18:
// EmptyStackException
Stack<Integer> s18 = new Stack<Integer>();
s18.addAll(testRandom(43));
while (s18.pop() != null);
// Originally ThreadDeath, which works when running from Dr. Java but not when
// running on cmd line. Seems that Dr. Java provides its own version of
// Thread.UncaughtExceptionHandler that prints out ThreadDeath.
// Please make do with this boring Exception
break;
case 19:
// NegativeArraySizeException
Array.newInstance(Integer.TYPE, -1);
// Do they have to create such a specific Exception?
break;
case 20:
// OutOfMemoryError
Array.newInstance(Integer.TYPE, 1000, 1000, 1000, 1000);
break;
case 21:
// UnsupportedCharsetException
// UCS-2 is superseded by UTF-16
Charset cs21 = Charset.forName("UCS-2");
CharsetEncoder ce21 = cs21.newEncoder();
// Just in case...
cs21 = Charset.forName("o_O");
// "o_O" is a (syntactically) valid charset name, so it throws UnsupportedCharsetException
break;
case 22:
// IllegalCharsetNameException
boolean isSupported;
isSupported = Charset.isSupported("o_O");
isSupported = Charset.isSupported("+_+");
Charset cs22 = Charset.forName("MerryChristmas!Hohoho!");
// This is getting stupid...
break;
case 23:
// NoClassDefFoundError
File f = new File("ToBeRemoved.class");
f.delete();
ToBeRemoved o23 = new ToBeRemoved();
// This shows that class is loaded on demand
break;
case 24:
// InputMismatchException
Scanner sc = new Scanner("2987654321");
sc.nextInt();
// Out of range
break;
case 25:
// Formatter class has many RuntimeException defined
// DuplicateFormatFlagsException
System.out.printf("%0000000000000000000000000000000000000000000000000005%d\n", 42);
break;
case 26:
// FormatFlagsConversionMismatchException
System.out.printf("%,d\n", Integer.MAX_VALUE);
System.out.printf("%,x\n", Integer.MAX_VALUE);
// Thousand separator is only applicable to base 10
System.out.printf("%(5.4f\n", Math.PI);
System.out.printf("%(5.4f\n", -Math.PI);
System.out.printf("%(5.4a\n", -Math.PI);
// '(' flag is used to surround negative value with "( )" instead of prefixing with '-'
// '(' can't be used with conversion 'a'
break;
case 27:
// IllegalFormatCodePointException
System.out.printf("%c", Character.MAX_CODE_POINT + 1);
// Larger than current Unicode maximum code point (0x10FFFF)
break;
case 28:
// IllegalFormatConversionException
String i28 = "0";
System.out.printf("%d", i28);
// A boring example
break;
case 29:
// IllegalFormatFlagsException
System.out.printf("% d\n", Integer.MAX_VALUE);
System.out.printf("% d\n", Integer.MIN_VALUE);
System.out.printf("%+d\n", Integer.MAX_VALUE);
System.out.printf("%+d\n", Integer.MIN_VALUE);
System.out.printf("% +d\n", Integer.MIN_VALUE);
// Use either ' ' or '+ ' flag, not both, since they are mutually exclusive
break;
case 30:
// IllegalFormatPrecisionException
System.out.printf("%5.4f\n", Math.PI);
System.out.printf("%5.4a\n", Math.PI);
System.out.printf("%5.4x\n", Math.PI);
// Precision does not apply to 'x', which is integer hexadecimal conversion
// To print a floating point number in hexadecimal, use conversion 'a'
break;
case 31:
// IllegalFormatWidthException
System.out.printf("%3n");
// For conversion n, width is not supported
break;
case 32:
// MissingFormatArgumentException
System.out.printf("%s\n%<s", "Pointing to previous argument\n");
System.out.printf("%<s", "Pointing to previous argument");
// No previous argument
break;
case 33:
// MissingFormatWidthException
System.out.printf("%5d %<d\n", 42); // Pad left
System.out.printf("%-5d %<d\n", 42); // Pad right
System.out.printf("%-d\n", 42);
// Missing width
break;
case 34:
// UnknownFormatConversionException
System.out.printf("%q", "Shouldn't work");
// No format conversion %q
// UnknownFormatFlagsException cannot be thrown by Formatter class in
// Oracle's implementation, since the flags have been checked in the regex
// used to recognize the format string
break;
case 35:
// IllformedLocaleException
System.out.printf(new Locale("ja"), "%tA %<tB %<tD %<tT %<tZ %<tY\n", new Date());
System.out.printf(new Locale.Builder().setLanguage("ja").setScript("JA").setRegion("JA").build(), "%tA %<tB %<tD %<tT %<tZ %<tf\n", new Date());
// Thrown by Locale.Builder.setScript()
break;
case 36:
// NullPointerException
Pattern p36 = Pattern.compile("a(b)?c");
Matcher m36 = p36.matcher("ac");
if (m36.find()) {
for (int i36 = 0; i36 <= m36.groupCount(); i36++) {
// Use Matcher#end(num) - Matcher#start(num) for length instead
System.out.printf("%3d [%d]: %s\n", i36, m36.group(i36).length(), m36.group(i36));
}
}
break;
case 37:
// AccessControlException
System.setSecurityManager(new SecurityManager());
System.setSecurityManager(new SecurityManager());
break;
case 38:
// SecurityException
// Implementation-dependent
Class ϲlass = Class.class;
Constructor[] constructors = ϲlass.getDeclaredConstructors();
for (Constructor constructor: constructors) {
constructor.setAccessible(true);
try {
Class Сlass = (Class) constructor.newInstance();
} catch (Throwable e) {
System.out.println(e.getMessage());
}
// The code should reach here without any Exception... right?
}
// It is obvious once you run the code
// There are very few ways to get SecurityException (and not one of its subclasses)
// This is one of the ways
break;
case 39:
// UnknownFormatFlagsException
// Implementation-dependent
try {
System.out.printf("%=d", "20");
} catch (Exception e) {
// Just to show the original Exception
System.out.println(e.getClass());
}
Class classFormatter = Formatter.class;
Field[] fs39 = classFormatter.getDeclaredFields();
boolean patternFound = false;
for (Field f39: fs39) {
if (Pattern.class.isAssignableFrom(f39.getType())) {
f39.setAccessible(true);
// Add = to the list of flags
try {
f39.set(classFormatter, Pattern.compile("%(\\d+\\$)?([-#+ 0,(\\<=]*)?(\\d+)?(\\.\\d+)?([tT])?([a-zA-Z%])"));
} catch (IllegalAccessException e) {
System.out.println(e.getMessage());
}
patternFound = true;
}
}
if (patternFound) {
System.out.printf("%=d", "20");
}
// As discussed before UnknownFormatFlagsException cannot be thrown by Oracle's
// current implementation. The reflection code above add = to the list of flags
// to be parsed to enable the path to the UnknownFormatFlagsException.
break;
}
}
/*
* This method is used to check whether all numbers under d are generated when we call
* new Object().hashCode() % d.
*
* However, hashCode() is later replaced by System.nanoTime(), since it got stuck at
* some values when the JVM is stopped and restarted every time (running on command line).
*/
private static List<Integer> testRandom(int d) {
List<Integer> k = new ArrayList<Integer>();
for (int i = 0; i < 250; i++) {
k.add(new Object().hashCode() % d);
}
Collections.sort(k);
System.out.println(k);
return k;
}
}
class ToBeRemoved {};
class Static {
static public int k = 0;
static {
System.out.println(0/0);
}
}
异常和错误列表
按照在switch-case语句中声明的顺序。总共有37 Exception
秒和3 Error
秒。
- PatternSyntaxException(通过中的错误
Pattern
,以无聊的情况作为备份)
- StringIndexOutOfBoundsException(通过中的错误
Pattern
,以无聊的情况作为备份)
- IllegalArgumentException(可帮助我查找中的错误
Pattern
,以无聊的情况作为备份)
- StackOverflowError(通过中的递归实现
Pattern
,以无聊的情况作为备份)
- NumberFormatException(显示
$
in Pattern
可以在最后一行终止符之前匹配)
- IllegalStateException(通过
Matcher
不执行匹配就访问匹配的组)
- ArrayIndexOutOfBoundsException(显示的令人困惑的行为
split(String regex)
)
- ConcurrentModificationException(通过在for-each循环中修改Collection)
- ArithmeticException(通过整数除以0)
- ExceptionInInitializerError(通过
Exception
在类初始化期间引起)
- BufferOverflowException(
java.nio.*
-specific Exception
)
- BufferUnderflowException(
java.nio.*
特异性Exception
)
- InvalidMarkException(
java.nio.*
特异性Exception
)
- IndexOutOfBoundsException(通过引用替换中不存在的捕获组)
- ClassCastException
- NoSuchElementException
- ArrayStoreException
- IllegalThreadStateException
- EmptyStackException(
java.util.Stack
-specific Exception
)
- NegativeArraySizeException
- OutOfMemoryError(通过大数组的无聊分配)
- UnsupportedCharsetException
- IllegalCharsetNameException(显示何时
Charset.isSupported(String name)
返回false或throws Exception
)
- NoClassDefFoundError(显示在第一次访问方法/构造函数或字段时加载了类)
- InputMismatchException时(
java.util.Scanner
特异性Exception
)
- DuplicateFormatFlagsException(从这里到35是
java.util.Formatter
-specific Exception
的)
- FormatFlagsConversionMismatchException(带有有趣的格式语法示例)
- IllegalFormatCodePointException
- IllegalFormatConversionException
- IllegalFormatFlagsException
- IllegalFormatPrecisionException
- IllegalFormatWidthException
- MissingFormatArgumentException(带有有趣的格式语法示例)
- MissingFormatWidthException
- UnknownFormatConversionException
- IllformedLocaleException
- 空指针异常
- AccessControlException(显示默认设置
SecurityManager
可用)
- SecurityException(通过调用
Class
类的构造函数)
- UnknownFormatFlagsException(显示
Exception
不能在Oracle的实现中抛出,没有备份)