자바, 400
자바입니다 축복 많은으로 (?) Exception들과 Error의. Exception단일 클래스의 조작과 관련된 많은 것들이 있습니다 . 가장 극단적 인 경우 중 하나의 예로서, 클래스 전용으로 10 Exception초 이상 (모두 서브 클래스 IllegalFormatException) Formatter이 있으며 코드를 (거의) 모두 던지기 위해 시간이 걸렸습니다.
내 현재 답변에는 40 가지 Exception의 s / Errors System.nanoTime()가 있으며 정수 로 모듈로에 따라 무작위로 실행 됩니다.
이 방법은 경과 시간을 측정하는 데만 사용할 수 있으며 다른 시스템 또는 벽시계 시간 개념과 관련이 없습니다. 반환 된 값은 고정되었지만 임의의 원점 시간 (나중에 값이 음수 일 수 있음) 이후 나노초를 나타냅니다. Java 가상 머신의 인스턴스에서이 메소드의 모든 호출에서 동일한 오리진이 사용됩니다. 다른 가상 머신 인스턴스는 다른 오리진을 사용할 수 있습니다.
위의 방법은 "3. 주 프로그램 스레드의 시작에 상대적으로 계산되지 않으면 틱 또는 CPU주기 수를 사용할 수 없음"에 해당하므로 허용되어야합니다 .
편집 지시
코드를 실행하려면 Oracle의 JRE / JDK 또는 OpenJDK 를 사용하는 것이 좋습니다. 그렇지 않으면 일부 예외는 참조 구현의 내부 세부 정보에 의존하고 신뢰할 수있는 폴 백이 없기 때문에 일부 예외가 발생하지 않을 수 있습니다.
아래 코드는에 성공적으로 컴파일 javac 1.7.0_11되고에 대한 모든 예외를 생성합니다 java 1.7.0_51.
이 코드를 실행하려면 아래 코드를 유니 코드 인식 편집기 (예 : 메모장 ++)에 복사하여 붙여넣고 UTF-16으로 저장해야합니다 (BOM이 작성되는 한 Big-Endian 또는 Little-Endian은 중요하지 않음) .
작업 디렉토리 ( 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.*-specific Exception)
- InvalidMarkException (
java.nio.*-specific Exception)
- IndexOutOfBoundsException (대체로 존재하지 않는 캡처 그룹에 대한 참조를 통해)
- ClassCastException
- NoSuchElementException
- ArrayStoreException
- IllegalThreadStateException
- EmptyStackException (
java.util.Stack-specific Exception)
- NegativeArraySizeException
- OutOfMemoryError (큰 배열의 지루한 할당을 통해)
- UnsupportedCharsetException
- IllegalCharsetNameException (
Charset.isSupported(String name)false를 반환 하거나을 던질 때 표시 Exception)
- NoClassDefFoundError (메소드 / 생성자 또는 필드에 처음 액세스 할 때 클래스가로드됨을 나타냄)
- InputMismatchException (
java.util.Scanner-specific Exception)
- DuplicateFormatFlagsException (여기에서 35까지는
java.util.Formatter특정입니다 Exception)
- FormatFlagsConversionMismatchException (형식 구문의 흥미로운 예와 함께)
- IllegalFormatCodePointException
- IllegalFormatConversionException
- IllegalFormatFlagsException
- IllegalFormatPrecisionException
- IllegalFormatWidthException
- MissingFormatArgumentException (형식 구문의 흥미로운 예와 함께)
- MissingFormatWidthException
- UnknownFormatConversionException
- IllformedLocaleException
- NullPointerException
- AccessControlException (기본값
SecurityManager을 사용할 수 있음을 나타냄)
- SecurityException (
Class클래스 생성자를 호출하여 )
- UnknownFormatFlagsException (
ExceptionOracle 구현에서 백업을 수행 할 수 없음)