本文原創,轉載請注明原處!

紅色代表的是基本組件:包(Package),修飾符(modifier),類(Class),字段(Field),構造器(Constructor)和方法(Method)。
黃色代表的是泛型組件:可定義泛型的元素(GenericDeclaration),類型(Type),泛型(TypeVariable),泛型參數類(ParameterizedType),泛型數組(GenericArrayType),通配符(WildcardType)。
藍色代表的是注解組件:可被注解的元素(AnnotatedElement),注解後的類型(AnnotatedType),注解(Annotation),其它。
類不是單純的指class定義的類,它是包括基本數據類型和數組,還包括class,interface,@interface,enum等定義出來的類型。
平常所用到的,所定義出來的類型,都可以歸為現在所講述的這個“類”,但它不包括泛型,雖然說泛型可以作為一個類型來使用。
接口:Type,GenericDeclaration,AnnotatedElement
示例:
public class Test {
public static void main(String[] params) throws ClassNotFoundException {
Class<?> clazz = Class.forName("test.TestClass$TestInnerClass");
System.out.println(clazz.getName());
System.out.println(clazz.getCanonicalName());
System.out.println(clazz.getSimpleName());
/*
運行結果:
test.TestClass$TestInnerClass
test.TestClass.TestInnerClass
TestInnerClass
*/
}
}
test/TestClass.java
public class TestClass {
public class TestInnerClass {
}
}
public class Test {
public static void main(String[] params) {
print("基本數據類型", int.class);
/*
輸出結果:
基本數據類型 -> 是否基本數據類型=true
基本數據類型 -> 是否數組= false
基本數據類型 -> 是否接口= false
基本數據類型 -> 是否注解= false
基本數據類型 -> 是否枚舉= false
*/
System.out.println("-------------------------");
print("數組", int[].class);
/*
輸出結果:
數組 -> 是否基本數據類型=false
數組 -> 是否數組= true
數組 -> 是否接口= false
數組 -> 是否注解= false
數組 -> 是否枚舉= false
*/
System.out.println("-------------------------");
print("接口", TestInterface.class);
/*
輸出結果:
接口 -> 是否基本數據類型=false
接口 -> 是否數組= false
接口 -> 是否接口= true
接口 -> 是否注解= false
接口 -> 是否枚舉= false
*/
System.out.println("-------------------------");
print("注解", TestAnnotation.class);
/*
輸出結果:
注解 -> 是否基本數據類型=false
注解 -> 是否數組= false
注解 -> 是否接口= true
注解 -> 是否注解= true
注解 -> 是否枚舉= false
*/
System.out.println("-------------------------");
print("枚舉", TestEnum.class);
/*
輸出結果:
枚舉 -> 是否基本數據類型=false
枚舉 -> 是否數組= false
枚舉 -> 是否接口= false
枚舉 -> 是否注解= false
枚舉 -> 是否枚舉= true
*/
System.out.println("-------------------------");
print("類", TestClass.class);
/*
輸出結果:
類 -> 是否基本數據類型=false
類 -> 是否數組= false
類 -> 是否接口= false
類 -> 是否注解= false
類 -> 是否枚舉= false
*/
}
public static void print(String name, Class<?> clazz){
System.out.println(name + " -> 是否基本數據類型=" + clazz.isPrimitive());
System.out.println(name + " -> 是否數組=\t" + clazz.isArray());
System.out.println(name + " -> 是否接口=\t" + clazz.isInterface());
System.out.println(name + " -> 是否注解=\t" + clazz.isAnnotation());
System.out.println(name + " -> 是否枚舉=\t" + clazz.isEnum());
}
public static class TestClass { }
public static interface TestInterface { }
public static @interface TestAnnotation { }
public static enum TestEnum { }
}
注意:注解既是注解類型,又是接口類型,但它不能像接口一樣,可以被實現。
示例:
public class Test {
public static void main(String[] params) {
System.out.println(int[].class.getComponentType());
System.out.println(int[][].class.getComponentType());
/*
輸出結果:
int
class [I
*/
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Modifier.toString(TestClass.class.getModifiers()));
// 輸出結果:
// public static final
}
public static final class TestClass {
}
}
網絡上查閱中,其中對內部類的劃分有常規內部類,靜態內部類,局部內部類,匿名內部類。下面的述語中,成員內部類是指常規內部類與靜態內部類。
示例:
public class Test {
public static void main(String[] params) {
new Test().test();
}
public void test(){
printInnerClass("常規內部類", Test.InnerClass.InnerClass2.class);
/*
輸出結果:
常規內部類 -> DeclaringClass= class Test$InnerClass
常規內部類 -> EnclosingClass= class Test$InnerClass
常規內部類 -> EnclosingConstructor=null
常規內部類 -> EnclosingMethod= null
常規內部類 -> 是否成員內部類= true
常規內部類 -> 是否局部內部類= false
常規內部類 -> 是否匿名內部類= false
*/
System.out.println("---------------------------------------------------------------------------------------");
printInnerClass("靜態內部類", StaticInnerClass.StaticInnerClass2.class);
/*
輸出結果:
靜態內部類 -> DeclaringClass= class Test$StaticInnerClass
靜態內部類 -> EnclosingClass= class Test$StaticInnerClass
靜態內部類 -> EnclosingConstructor=null
靜態內部類 -> EnclosingMethod= null
靜態內部類 -> 是否成員內部類= true
靜態內部類 -> 是否局部內部類= false
靜態內部類 -> 是否匿名內部類= false
*/
System.out.println("---------------------------------------------------------------------------------------");
class LocalInnerClass { }
printInnerClass("局部內部類", LocalInnerClass.class);
/*
輸出結果:
局部內部類 -> DeclaringClass= null
局部內部類 -> EnclosingClass= class Test
局部內部類 -> EnclosingConstructor=null
局部內部類 -> EnclosingMethod= public void Test.test()
局部內部類 -> 是否成員內部類= false
局部內部類 -> 是否局部內部類= true
局部內部類 -> 是否匿名內部類= false
*/
System.out.println("---------------------------------------------------------------------------------------");
Object obj = new Object(){ };
printInnerClass("匿名內部類", obj.getClass());
/*
輸出結果:
匿名內部類 -> DeclaringClass= null
匿名內部類 -> EnclosingClass= class Test
匿名內部類 -> EnclosingConstructor=null
匿名內部類 -> EnclosingMethod= public void Test.test()
匿名內部類 -> 是否成員內部類= false
匿名內部類 -> 是否局部內部類= false
匿名內部類 -> 是否匿名內部類= true
*/
}
public static void printInnerClass(String name, Class<?> clazz){
System.out.println(name + " -> DeclaringClass=\t" + clazz.getDeclaringClass());
System.out.println(name + " -> EnclosingClass=\t" + clazz.getEnclosingClass());
System.out.println(name + " -> EnclosingConstructor=" + clazz.getEnclosingConstructor());
System.out.println(name + " -> EnclosingMethod=\t" + clazz.getEnclosingMethod());
System.out.println(name + " -> 是否成員內部類=\t" + clazz.isMemberClass());
System.out.println(name + " -> 是否局部內部類=\t" + clazz.isLocalClass());
System.out.println(name + " -> 是否匿名內部類=\t" + clazz.isAnonymousClass());
}
public class InnerClass {
public class InnerClass2 {
}
}
public static class StaticInnerClass {
public static class StaticInnerClass2 {
}
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(TestClass.class.getSuperclass());
System.out.println(TestClass.class.getGenericSuperclass());
System.out.println(TestClass.class.getAnnotatedSuperclass());
/*
運行結果:
class Test$TestSuperClass
Test.Test$TestSuperClass<java.lang.Integer>
sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482
*/
}
public class TestSuperClass<T> {
}
public class TestClass extends @TestAnnotation TestSuperClass<Integer>{
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getInterfaces()));
System.out.println(Arrays.toString(TestClass.class.getGenericInterfaces()));
System.out.println(Arrays.toString(TestClass.class.getAnnotatedInterfaces()));
/*
運行結果:
[interface Test$TestInterface]
[Test.Test$TestInterface<java.lang.Integer>]
[sun.reflect.annotation.AnnotatedTypeFactory$AnnotatedParameterizedTypeImpl@a14482]
*/
}
public interface TestSuperInterface {
}
public interface TestInterface<T> extends TestSuperInterface {
}
public class TestClass implements @TestAnnotation TestInterface<Integer>{
}
@Target(ElementType.TYPE_USE)
@Retention(RetentionPolicy.RUNTIME)
public @interface TestAnnotation {
}
}
用例:
public class Test {
public static void main(String[] params) {
test(Object.class);
System.out.println("---------------------------------");
test(TestClass.class);
/*
輸出結果:
test方法 -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類
test方法 -> 這個clazz不是TestSuperClass類型或其子類
---------------------------------
test方法 -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類
test方法 -> 確認這個clazz是TestSuperClass類型或其子類
*/
}
public static Class<? extends TestSuperClass> test(Class<?> clazz){
System.out.println("test -> 獲得一個clazz,但不確定它是否為TestSuperClass類型或其子類");
if(TestSuperClass.class.isAssignableFrom(clazz)){
System.out.println("test -> 確認這個clazz是TestSuperClass類型或其子類");
return clazz.asSubclass(TestSuperClass.class);
}
System.out.println("test -> 這個clazz不是TestSuperClass類型或其子類");
return null;
}
public class TestSuperClass {
}
public class TestClass extends TestSuperClass {
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getClasses()));
System.out.println("---------------------------------");
System.out.println(Arrays.toString(TestClass.class.getDeclaredClasses()));
/*
輸出結果:
[class Test$TestClass$TestMemberClass3, class Test$TestSuperClass$TestSuperMemberClass3]
---------------------------------
[class Test$TestClass$TestMemberClass1, class Test$TestClass$TestMemberClass2, class Test$TestClass$TestMemberClass3]
*/
}
public class TestSuperClass {
private class TestSuperMemberClass1 {
}
protected class TestSuperMemberClass2 {
}
public class TestSuperMemberClass3 {
}
}
public class TestClass extends TestSuperClass {
private class TestMemberClass1 {
}
protected class TestMemberClass2 {
}
public class TestMemberClass3 {
}
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getConstructors()));
System.out.println(Arrays.toString(TestClass.class.getDeclaredConstructors()));
/*
運行結果:
[public Test$TestClass(Test,long)]
[private Test$TestClass(Test,short), protected Test$TestClass(Test,int), public Test$TestClass(Test,long)]
*/
}
public class TestClass {
private TestClass(short i){
}
protected TestClass(int i){
}
public TestClass(long l){
}
}
}
示例:
public class Test {
public static void main(String[] params) {
System.out.println(Arrays.toString(TestClass.class.getMethods()));
System.out.println("----------------------------------");
System.out.println(Arrays.toString(TestClass.class.getDeclaredMethods()));
/*
運行結果:
[public void Test$TestClass.test(long), public void Test$TestSuperClass.superTest(long), 省略Object的方法……]
----------------------------------
[public void Test$TestClass.test(long), protected void Test$TestClass.test(int), private void Test$TestClass.test(short)]
*/
}
public class TestSuperClass {
private void superTest(short i){
}
protected void superTest(int i){
}
public void superTest(long l){
}
}
public class TestClass extends TestSuperClass {
private void test(short i){
}
protected void test(int i){
}
public void test(long l){
}
}
}
與方法同理……
示例:
test/Test.java
public class Test {
public static void main(String[] params) {
Test.class.getClassLoader().setClassAssertionStatus(TestAssert.class.getName(), true);
TestAssert testAssert2 = new TestAssert();
testAssert2.test();
/*
運行結果:
TestAssert -> 斷言是否已打開=true
Exception in thread "main" java.lang.AssertionError: 斷言信息!
at test.TestAssert.test(TestAssert.java:6)
at test.Test.main(Test.java:10)
*/
}
}
test/TestAssert.java
public class TestAssert {
public void test(){
System.out.println("TestAssert -> 斷言是否已打開=" + TestAssert.class.desiredAssertionStatus());
assert false : "斷言信息!";
}
}
注:打開斷言功能,還可以使用“-ea”參數打開。