反射
new只能用于编译期就能确定的类型, 而反射可以在运行时才确定类型并创建其对象.
获取class对象的机制
Filed[] files
Constructor[] constructor
Method[] method
相对应的get和getDeclared方法来获得成员方法、构造放方法、和普通方法
class.forname("")
类名.class 多用于参数的传递
多用于对象获得字节码文件
三种方式
new 三个对象肯定是false,内存空间是不一样
通过反射生成的对象,内存空间是一样的。实际上只有一个Class。
public class refulectDemo1 {
/**
* 1.Class.forName("全类名"):将字节码文件加载进内存,返回class对象
2.类名.class:通过类名的class获取
3.对象.getClass(): getClass()方法在object类当中定义着
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws Exception {
// 1.Class.forName("全类名"):
Class class1 = Class.forName("reflect.Person");
System.out.println(class1);
//2.类名.class:通过类名的class获取
Class class2 = Person.class;
System.out.println(class2);
//3.对象.getClass()
Person person = new Person();
Class class3 = person.getClass();
System.out.println(class3);
}
}
结论:
同一类加载器加载的文件(*.class)在一次程序运行过程中,只会被加载一次,不论你通过那种方式获取的class对象都是同一个。
-
Filed Filed[]
-
get Filed是获取指定的名称
-
public可以用get Filed直接获取
-
而getDeclaredFiled();
-
Constructor Constructor[]
-
Methode Method[]
*class对象功能
*class对象功能
*获取功能
· 1.获取成员变量们
1.Field[] getFields() :获取所有public修饰的成员变量
2.Field getField(String name):获取指定名称的
3.Field[] getDeclaredFilds():获取所有的成员变量,不考虑修饰符
4.Field getDeclaredField(String name)
2.获取构造方法们
1.Constructor<?>[] getConstructors()
2.Constructor<T> getConstructor(类<?>...parameterTypes)
3.Constructor<?>[] getDeclaredConstructors()
4.Constructor<T> getDeclaredConstructors(类<?>...parameterTypes)
3.获取方法名
1.Method[] getMethod()
2.Method getMethod(String name,类<?>... parameterTypes)
3.Method[] getDeclaredMethod()
4.Method getDeclaredMethod(String name,类<?>... parameterTypes)
4.获取类名
String getName()
Field
public static void main(String[] args) throws Exception {
//0.获取Person的Class对象
Class personClass = Person.class;
/*
1. 获取成员变量们
* Field[] getFields()
* Field getField(String name)
* Field[] getDeclaredFields()
* Field getDeclaredField(String name)
*/
//1.Field[] getFields()获取所有public修饰的成员变量
Field[] fields = personClass.getFields();
for (Field field : fields) {
System.out.println(field);
}
System.out.println("------------");
//2.Field getField(String name)
Field a = personClass.getField("a");
//获取成员变量a 的值
Person p = new Person();
Object value = a.get(p);
System.out.println(value);
//设置a的值
a.set(p,"张三");
System.out.println(p);
System.out.println("===================");
//Field[] getDeclaredFields():获取所有的成员变量,不考虑修饰符
Field[] declaredFields = personClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
System.out.println(declaredField);
}
//Field getDeclaredField(String name)
Field d = personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查
d.setAccessible(true);//暴力反射
Object value2 = d.get(p);
System.out.println(value2);
}
Constructor
*创建对象
*T newInstance(Object... initarges)
*如果使用空参数构造方法,此操作可以简化:class对象的newInstance方法
public static void main(String[] args) throws Exception {
//0.获取Person的class对象
Class personClass = Person.class;
//因为构造器的方法名称是相同的,不同的是参数列表,所以我们可以根据不同的参数列表来找到构造器
Constructor constructor = personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象
Object perObject = constructor.newInstance("张三",20);
System.out.println(perObject);
System.out.println("-------------------------------");
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor1);
//创建对象
Object perObject1 = constructor1.newInstance();
System.out.println(perObject1);
System.out.println("-------------------------------");
Object o = personClass.newInstance();
System.out.println(o);
}
Method
*执行方法
*object invoke(Object object,Object... ages)
*获取方法名称
*String getName:获取方法名
public static void main(String[] args) throws Exception {
//0.获取Person的class对象
Class personClass = Person.class;
//获取指定名称的方法,方法无参
Method eat_method = personClass.getMethod("eat");
//执行方法
Person person =new Person();
eat_method.invoke(person);
//获取指定名称的方法,方法有参
Method eat_method1 = personClass.getMethod("eat",String.class);
//执行方法
eat_method1.invoke(person,"饭");
//获取所有public修饰的方法
Method[] methods = personClass.getMethods();
for (Method method : methods) {
System.out.println(method);
//获取方法的名称
String name = method.getName();
System.out.println(name);
}
}
暴力反射
构造方法和暴力反射
public static void main(String[] args) {
try {
Class class1 = Class.forName("com.Reflection.Driver");
Field afield = class1.getField("str");
Driver driver0 = new Driver();
Object obj = afield.get(driver0);
System.out.println(afield);
System.out.println(obj);
Driver driver = new Driver();
Field namefield = class1.getDeclaredField("name");
namefield.setAccessible(true);
namefield.set(driver,1);
Object strobj = namefield.get(driver);
System.out.println(driver.toString());
Constructor[] constructors = class1.getConstructors();
System.out.println(Arrays.toString(constructors));
Constructor[] constructors1=class1.getDeclaredConstructors();
System.out.println(Arrays.toString(constructors1));
Constructor constructor = class1.getConstructor(String.class);
System.out.println(constructor);
Constructor constructor1 = class1.getDeclaredConstructor(int.class,int.class);
constructor1.setAccessible(true);
Object object = constructor1.newInstance(2,12);
System.out.println(object);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
普通方法
普通方法和暴力反射
public static void main(String[] args) {
try {
Class class1 = Class.forName("com.Reflection.Driver");
Method[] methods = class1.getMethods();
Method methods1 = class1.getDeclaredMethod("run",null);
methods1.setAccessible(true);
//Object obj = methods1.getName();
//System.out.println(obj);
System.out.println(methods1);
Driver driver = new Driver();
methods1.invoke(driver,null);
// for (int i = 0; i < methods.length; i++) {
// System.out.println(methods[i]);
// }
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
反射JavaBean
package com.JavaBean1105;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Member;
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) {
// 作业:给定一个java bean,获取该类的构造方法来构造对象,
// 获取该类的名称和该类中每一个方法的变量方法的名称,
// 并执行get方法。给每一个变量赋值,并获取值,执行每一个构造方法
try {
//获取含参构造器
Class class1 = Class.forName("com.JavaBean1105.Body");
Constructor constructor = class1.getDeclaredConstructor(int.class,String.class);
constructor.setAccessible(true);
//用含参构造器构造对象
Object object = constructor.newInstance(1,"TheBody");
System.out.println("构造方法构造:"+object);
System.out.println("获取类的名称"+class1.toString());
Method[] methods = class1.getDeclaredMethods();
System.out.println("获取所有方法");
Constructor[] constructors = class1.getDeclaredConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("构造方法["+(i+1)+"] "+constructors[i]);
}
for (int i = 0; i < methods.length; i++) {
System.out.println("非构造方法["+(i+1)+"] "+methods[i]);
}
System.out.println("------------------------------------------------------");
//获得无参构造器
Constructor constructornull = class1.getDeclaredConstructor(null);
constructornull.setAccessible(true);
//用无参构造器构造空对象 objectnull Setter 和 Getter都可以用
Object objectnull = constructornull.newInstance(null);
//获得Setter
Method method = class1.getDeclaredMethod("setId",int.class);
Method method1 = class1.getDeclaredMethod("setName",String.class);
method.setAccessible(true);
method1.setAccessible(true);
method.invoke(objectnull,123);
method1.invoke(objectnull,"空对象setter");
System.out.println("private Setter: "+objectnull.toString());
System.out.println("------------------------------------------------------");
Method method2 = class1.getDeclaredMethod("getId",null);
Method method3 = class1.getDeclaredMethod("getName",null);
method2.setAccessible(true);
method3.setAccessible(true);
System.out.println("private Getter id: "+method2.invoke(objectnull,null));
System.out.println("private Getter name: "+method3.invoke(objectnull,null));
System.out.println("------------------------------------------------------");
Method method4 = class1.getDeclaredMethod("toString1",null);
method4.setAccessible(true);
System.out.println("private String toString1(): "+method4.invoke(objectnull,null));
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
db.properties
Properties properties = new Properties();
ClassLoader classLoader = FrameUtil.class.getClassLoader();
InputStream inputStream = classLoader.getResourceAsStream("db.properties");
properties.load(inputStream);
String classname = properties.getProperty("classname");
System.out.println(classname);