要去看埃菲尔铁塔的顶
欢迎关注本人微博:t.cn/RGSLVUk
Java 反射机制 ,大致理解如下, 其实Class 也是一个类,每一个类都有自己的类描述信息,
1.获取Class对象
这样就是一个Class类的对象 (优势就是 安全,性能好)
Class<ClassTest> clazz = ClassTest.class;
亦或是这样(优势就是 只需要一个类的名称 , 可能会抛出ClassNotFoundException)
Class inClazz = Class.forName("ComplieClassLoader.ClassTest$Inner");
也可能是这样 (从class字节文件 生成Class )
defineClass( "className",raw,0,raw.length)
也可以是
调用类对象的 .getClass() 方法
2.根据Class对象生成类对象
class.newInstance() 方法 ,此方法调用默认构造器
也可以指定构造器 来生成 类对象
class.getConstructor(参数) . newInstance("")
有了类对象,就可以调用里面的方法了,利用反射可以获取方法的对象,然后调用方法对象的的 invoke() 方法,考虑传入类对象,以及参数信息,就可以成功调用方法。
3.关于反射来获取对象中属性值
Field xxxField = getDeclaredField() 方法来获取属性值
可以改变属性的可见性
xxxField.setAccessible(TRUE) 设置为可见
xxxField.set() / .get() 设置 / 获取 属性值
------------------------< 反射初探 > ------------------------
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class ClassTest
{
private ClassTest()
{ }
private ClassTest(String name)
{
System.out.println("ClassTest构造器" + " 参数是 " + name);
}
public void info(String str)
{
System.out.println("调用 info方法 " + " 参数是 " + str);
}
class Inner//内部类
{
}
public static void main(String[] args) throws NoSuchMethodException, SecurityException, ClassNotFoundException
{
Class<ClassTest> clazz = ClassTest.class;
Constructor<?>[] ctors = clazz.getDeclaredConstructors();//获取构造器
System.out.println("ClassTest 的全部构造器如下:");
for(Constructor c : ctors)
{
System.out.println(c);
}
Method[] mtds = clazz.getMethods();
System.out.println("ClassTest 的全部 public 方法如下:");
for (Method md : mtds)
{
System.out.println(md);
}
System.out.println("ClassTest里带一个字符串参数的info 方法为: "+ clazz.getMethod("info", String.class));
System.out.println("ClassTest 的全部内部类");
Class<?>[] inners = clazz.getDeclaredClasses();
for(Class c : inners)
{
System.out.println(c);
}
Class inClazz = Class.forName("ComplieClassLoader.ClassTest$Inner");
System.out.println("inClazz对应的外部类是" + inClazz.getDeclaringClass());
System.out.println("ClassTest的包为 " + clazz.getPackage());
System.out.println("ClassTest的父类是" + clazz.getSuperclass());
}
}
------------------< 反射 >属性操作-------------------------
class Person
{
private String name;
private int age;
public String toString()
{
return "Person[" + name + " ," + age + "]";
}
}
public class FieldTest {
public static void main(String[] args) throws NoSuchFieldException, SecurityException,
IllegalArgumentException, IllegalAccessException
{
//利用反射来设置 属性值
Person p = new Person();
Class<Person> personClazz = Person.class;
Field nameField = personClazz.getDeclaredField("name");
nameField.setAccessible(true);
nameField.set(p, "Yllen");
Field ageField = personClazz.getDeclaredField("age");
ageField.setAccessible(true);
ageField.set(p, 22);
System.out.println(p);
}
}
-------反射 对象工厂---------
根据 文本所记录的类名称 生成类的实例,然后调用方法
< Spring 框架 > 机制
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class ObjectPoolFactory {
/**
* @param args
*/
private Map<String,Object> objectPool = new HashMap<>();
Properties config = new Properties();
//给定类名称 ,生成 实例
private Object createObject(String clazzName) throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
// 根据字符串获取 对应的class 对象
Class <?> clazz = Class.forName(clazzName);//得到这个类
return clazz.newInstance();//实例化一个对象 等同于 A a = new A(); 调用默认构造函数来创建对象
}
public void init(String fileName)
{
try{
FileInputStream fis = new FileInputStream(fileName);
config.load(fis);
}catch(IOException ex)
{
System.out.println("读取" + fileName + "异常");
}
}
public void initProperty() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException
{
for(String name : config.stringPropertyNames())
{
//
if(name.contains("%"))
{
String[] objAndProp = name.split("%");
Object target = getObject(objAndProp[0]);
String mtdName = "set" +
objAndProp[1].substring(0,1).toUpperCase() +
objAndProp[1].substring(1);
//通过target的getClass()获取它的实现类所对应的Class对象
Class<?> targetClass = target.getClass();
//获取该属性的setter方法
Method mtd = targetClass.getMethod(mtdName, String.class);
//invoke
mtd.invoke(target, config.getProperty(name));
}
}
}
public void initPool() throws FileNotFoundException, IOException, ClassNotFoundException, InstantiationException, IllegalAccessException
{
for(String name : config.stringPropertyNames())
{
//key - value 对,就根据value 创建一个对象
if(!name.contains("%"))
objectPool.put(name, createObject(config.getProperty(name)));
}
}
public Object getObject(String name)
{
return objectPool.get(name);
}
public static void main(String[] args) throws FileNotFoundException, ClassNotFoundException, InstantiationException, IllegalAccessException, IOException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
/*ObjectPoolFactory pf = new ObjectPoolFactory();
pf.initPool("obj.txt");
System.out.println(pf.getObject("a"));
System.out.println(pf.getObject("b"));
Object obj = pf.getObject("b");
*/
ObjectPoolFactory pf = new ObjectPoolFactory();
pf.init("extObj.txt"); //
pf.initPool();//load属性值
pf.initProperty();//拼装
System.out.println(pf.getObject("a"));
System.out.println("下面是调用 构造方法来创建实例");
Class<?> jframeClazz = Class.forName("javax.swing.JFrame");
Constructor ctor = jframeClazz.getConstructor(String.class);
Object objx = ctor.newInstance("测试窗口");
System.out.println(objx);
}
}