Java基礎--反射

反射是什麼

ClassLoader的認識

通過這邊精華博客來了解ClassLoader:

深入分析Java ClassLoader原理


反射涉及的對象:Class、Constructor、MethodFieldAnnotation相關泛型相關


通過代碼演示反射的效果:

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







發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章