反射是什麼
ClassLoader的認識
通過這邊精華博客來了解ClassLoader:
深入分析Java ClassLoader原理
反射涉及的對象:Class、Constructor、Method(Field)、Annotation相關、泛型相關
通過代碼演示反射的效果:
1.首先創建一個的接口
import java.io.Serializable;
public interface MyInterface extends Serializable{
}
2.創建一個註釋類
import static java.lang.annotation.ElementType.CONSTRUCTOR;
import static java.lang.annotation.ElementType.FIELD;
import static java.lang.annotation.ElementType.LOCAL_VARIABLE;
import static java.lang.annotation.ElementType.METHOD;
import static java.lang.annotation.ElementType.PARAMETER;
import static java.lang.annotation.ElementType.TYPE;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation {
String value();
}
3.創建一個繼承的類
public class Creature<T> {
public double weight;
public void breath(){
System.out.println("呼吸!");
}
}
4.創建一個Person對象並且實現上面的接口和繼承上面類
@MyAnnotation(value="atguigu")
public class Person extends Creature<String> implements Comparable,MyInterface{
public String name;
private int age;
int id;
//創建類時,儘量保留一個空參的構造器
public Person() {
super();
}
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
public Person(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@MyAnnotation(value="abc123")
public void show(){
System.out.println("我是一個人");
}
public void display(String nation) throws Exception{
System.out.print("我的國籍是:"+nation);
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public int compareTo(Object o) {
return 0;
}
class Bird{
}
}
5.1測試構造器對象
import java.lang.reflect.Constructor;
import org.junit.Test;
public class TestConstructor {
@Test
public void test1() throws Exception{
String className="com.atguigu.java.Person";
Class clazz=Class.forName(className);
//創建對應的運行時類的對象
//要想能夠創建成功:
//1.要求對應的運行時類要有空參的構造器
//2.構造器的權限修飾符的權限要足夠
Person p=(Person) clazz.newInstance();
System.out.println(p);
}
@Test
public void test2(){
Class clazz=Person.class;
Constructor[] cons=clazz.getDeclaredConstructors();
for(Constructor c:cons){
System.out.println(c);
}
}
}
5.2.測試效果:
test1的運行效果:
Person [name=null, age=0]
test2的運行效果:
public com.atguigu.java.Person()
public com.atguigu.java.Person(java.lang.String,int)
public com.atguigu.java.Person(java.lang.String)
6.1測試"方法"
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import org.junit.Test;
public class TestField {
@Test
public void test1(){
Class clazz=Person.class;
//1.getFields():只能獲取到運行時類中及其父類中聲明爲public的屬性
Field[] fields=clazz.getFields();
for(Field field:fields){
System.out.println(field);
}
//2.
Field[] fields1=clazz.getDeclaredFields();
for(Field field:fields1){
System.out.println(field);
}
}
/**
* 權限修飾符 變量類型 變量名
* 獲取屬性的各個部分的內容
*/
@Test
public void test2(){
Class clazz=Person.class;
Field[] fields=clazz.getDeclaredFields();
for(Field f:fields){
//1.獲取每個屬性的權限符
String str=Modifier.toString(f.getModifiers());
System.out.print(str +" ");
//2.獲取屬性的類型
Class type=f.getType();
System.out.print(type.getName()+" ");
//3.獲取屬性名
System.out.println(f.getName());
}
}
}
6.2.測試效果:
test1的運行效果:
public java.lang.String com.atguigu.java.Person.name
public double com.atguigu.java.Creature.weight
public java.lang.String com.atguigu.java.Person.name
private int com.atguigu.java.Person.age
int com.atguigu.java.Person.id
test2的運行效果:
public java.lang.String name
private int age
int id
7.1測試其他方面:
import java.lang.annotation.Annotation;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import org.junit.Test;
public class TestOthers {
@Test
public void test1() {
Class clazz = Person.class;
// 獲取運行時的父類
Class superClass = clazz.getSuperclass();
System.out.println(superClass);
//打印帶有泛型的父類
Type type = clazz.getGenericSuperclass();
System.out.println(type);
//獲取實現的接口
Class[] interfaces=clazz.getInterfaces();
for(Class i:interfaces){
System.out.println(i);
}
//獲取所在的包
Package p=clazz.getPackage();
System.out.println(p);
//獲取註解
Annotation[] anns=clazz.getAnnotations();
for(Annotation a:anns){
System.out.println(a);
}
}
//獲取父類的泛型
@Test
public void test2() {
Class clazz = Person.class;
Type type=clazz.getGenericSuperclass();
ParameterizedType param=(ParameterizedType) type;
//通過向下轉化爲Class
Type[] ars=param.getActualTypeArguments();
System.out.println(((Class)ars[0]).getName());
}
}
7.2.測試效果:
test1的運行效果:
class com.atguigu.java.Creature
com.atguigu.java.Creature<java.lang.String>
interface java.lang.Comparable
interface com.atguigu.java.MyInterface
package com.atguigu.java
@com.atguigu.java.MyAnnotation(value=atguigu)
test2的運行效果:
java.lang.String