Java反射技术(个人笔记)

 

首先是最基础的用法


public class Cat 
{
	String name = "123";
	public Cat()
	{
		System.out.println("null constructor");
	}
	public Cat( String name )
	{
		System.out.println(name);
	}
}

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.lang.reflect.Constructor;
import java.util.*;

import javax.swing.*;

import org.junit.Test;

public class Main
{

	@Test
	public static void main( String args[] )
	{
		
		try {
			//第①步
			//加载一个类到内存
			Class c = Class.forName("Cat");
		
			//加载类的第二种方式
			Class c2 = new Cat().getClass();
			
			//加载类的第三种方法
			Class c3 = Cat.class;
			
			//第②步
			//通过类获得构造对象Constructor
			
			//无参数的构造器
			Constructor constructor = c2.getConstructor(null);
			Cat cat = (Cat)constructor.newInstance(null);	//调用Cat中的无参数构造方法
			System.out.println(cat.name);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		
	}
	
	
	
}

 

然后稍微加一点难度(带参数的构造方法)

package mypackage;

import java.util.Vector;

public class Fish
{
	String name = "red fish";
	public Fish()
	{
		System.out.println("a new fish");
	}
	public Fish( String name )
	{
		System.out.println("a new new fish");
		this.name = name;
	}
	
	private Fish( Vector v )
	{
		System.out.println("a complex constructor");
	}
}

 

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;


public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Class c = Class.forName("mypackage.Fish");
			
			//此外,创建对象还有一种方法
			Fish fff = (Fish)c.newInstance();	//但是这种方法只能调用无参数构造方法
			
			Constructor constructor = c.getConstructor(null);
			Fish f = (Fish)constructor.newInstance(null);
			
			
			
			//获得一个带参数的构造器
			Constructor constructor2 = c.getConstructor(String.class);	//括号里应该填类
			Fish f2 = (Fish)constructor2.newInstance("yang");
			System.out.println(f2.name);
			
			//注意,这里用到的是getDeclaredConstructor,可以得到所有的(包括private),而之前的getconstructor只能得到public
			Constructor constructor3 = c.getDeclaredConstructor(Vector.class);
			
			//暴力反射,(因为该构造方法是私有的,但是对于反射,依然可以)
			constructor3.setAccessible(true); //写了这句话就能调用私有的
			//最后创建对象
			Fish f3 = (Fish)constructor3.newInstance(new Vector());
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

然后调用普通的方法

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;

//方法的反射
public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Fish f = new Fish();
			
			Class c = Class.forName("mypackage.Fish");
			
			
			//Fish中normalMethod方法 	public void normalMethod();
			Method method = c.getMethod("normalMethod", null);
			method.invoke(f, null);	//调用
			
			//反射  public String StringMethod(String name)
			method = c.getMethod("StringMethod", String.class);
			method.invoke(f, "这里填方法的参数");
			
			//反射public int[] ArrayMethod( String name )
			method = c.getMethod("ArrayMethod", String.class);
			int a[] = (int[])method.invoke(f, "string参数");
			System.out.println("a的值 "+a[0]);
			
			//反射  public static void staticMethod( int t )
			method = c.getMethod("staticMethod", int.class);
			method.invoke(null, 123);
			
			//反射public void specialMethod( String s[] )
			method = c.getMethod("specialMethod", String[].class);
			//method.invoke(f, new String[] {"11","22"}); 	//错误的写法,jdk本身的错误
			
			method.invoke(f,  (Object) new String[] {"11","22"}  );	//这里的强制转换有点特殊
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

package mypackage;

import java.awt.*;
import java.awt.image.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Vector;

import javax.swing.*;

import org.junit.Test;

//方法的反射
public class Mytest
{
	@Test
	public void test()
	{
	
		try {
			Fish f = new Fish();
			
			Class c = Class.forName("mypackage.Fish");
			
			
			Field field = c.getField("name");	//得到字段,
												//如果是私有,就用getDeclaredField,并且加上setAccessible(true);
	
			String s = (String)field.get(f);	//得到一个对象
			System.out.println(s);
			
			//或者下面的写法
			//下面的写法更详细
			
			Object obj = field.get(f);
			Class classType = obj.getClass();
			if( classType.equals(String.class) )
			{
				String value = (String)obj;
				System.out.println("string类");
				
			}
			
			//设置字段的值
			field.set(f, "asd");
			System.out.println(f.name);
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	
	}

}

 

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