1.什么是反射?
java的反射机制是指在运行状态时能够动态的获取一个类的属性信息以及调用它的方法,这样可以不用在编译时确定下类型,这对框架的编写十分有用,因此反射机制又被称为java框架的基石。反射可以获取的。
2.反射的使用
2.1 属性的获取与赋值
反射类:
public class Scholar {
public String publicContent;
private String privateContent;
public String getPrivateContent() {return privateContent;}
public void publicMethod(){
System.out.println("publicMethod");
}
public void publicMethod(String str){
System.out.println(str);
}
private void privateMethod(){
System.out.println("privateMethod");
}
private void privateMethod(String str){
System.out.println(str);
}
}
- 反射获取公有属性
public static void publicContent() throws Exception{
Class<?> scholarClass = Class.forName("Scholar");
Object instance = scholarClass.getConstructor().newInstance();
Field publicField = scholarClass.getField("publicContent");
publicField.set(instance,"publicContent");
}
- 反射获取私有属性
public static void privateContent() throws Exception{
Class<?> scholarClass = Class.forName("Scholar");
Object instance = scholarClass.getConstructor().newInstance();
Field publicField = scholarClass.getDeclaredField("privateContent");
//当调用私有方法时,需要设置权限
publicField.setAccessible(true);
publicField.set(instance,"privateContent");
}
- 反射调用公用方法(无参数)
public static void publicMethod() throws Exception{
Class<?> scholarClass = Class.forName("Scholar");
Object instance = scholarClass.getConstructor().newInstance();
Method publicMethod = scholarClass.getMethod("publicMethod");
publicMethod.invoke(instance);
}
- 反射调用公用方法(带参数)
public static void publicMethod(String str) throws Exception{
Class<?> scholarClass = Class.forName("Scholar");
Object instance = scholarClass.getConstructor().newInstance();
Method publicMethod = scholarClass.getMethod("publicMethod",String.class);
publicMethod.invoke(instance,str);
}
- 反射调用私有方法(带参数)
Class<?> scholarClass = Class.forName("Scholar");
Object instance = scholarClass.getConstructor().newInstance();
Method publicMethod = scholarClass.getDeclaredMethod("privateMethod",String.class);
publicMethod.setAccessible(true);
publicMethod.invoke(instance,str);
3.应用例子
一个简单的spring容器的实现例子。
<beans>
<bean id="wheel" class="simpleIoc.Wheel">
<property name="brand" value="Michelin"/>
<property name="specification" value="265/60 R18"/>
</bean>
<bean id="car" class="simpleIoc.Car">
<property name="name" value="Mercedes Benz G 500"/>
<property name="length" value="4717mm"/>
<property name="width" value="1855mm"/>
<property name="height" value="1949mm"/>
<property name="wheel" ref="wheel"/>
</bean>
</beans>
package simpleIoc;
import com.sun.deploy.model.Resource;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class SimpleIocFuXie {
private static final Map<String, Object> beans = new HashMap<String, Object>();
static {
try {
loadBean("simpleIoc.xml");
} catch (Exception e) {
e.printStackTrace();
}
}
public static Object getBean(String id) {
return beans.get(id);
}
private static void loadBean(String filePath) throws Exception {
InputStream is = SimpleIocFuXie.class.getClassLoader().getResourceAsStream(filePath);
//1.获取读对象
SAXReader reader = new SAXReader();
//2根据输入流获取文档
Document document = reader.read(is);
//3.获取根节点
Element root = document.getRootElement();
//4.
List<Element> beanElementList = root.selectNodes("//bean");
for (Element beanElement : beanElementList) {
String id = beanElement.attributeValue("id");
String className = beanElement.attributeValue("class");
//反射创建出类,接下来设置属性需要它
Class beanClass = Class.forName(className);
//创建实例
Object bean = beanClass.newInstance();
//开始处理property标签
List<Element> propertyElementList = beanElement.selectNodes("property");
for (Element propertyElement : propertyElementList) {
String fieldName = propertyElement.attributeValue("name");
String fieldValue = propertyElement.attributeValue("value");
System.out.println(beanClass.getName());
System.out.println(fieldName);
//根据属性名称获取对应的属性,并给他赋值
Field field = beanClass.getDeclaredField(fieldName);
field.setAccessible(true);
//没有value字段,说明是用的ref。
if (fieldValue == null) {
String ref = propertyElement.attributeValue("ref");
field.set(bean, getBean(ref));
} else {
field.set(bean,fieldValue);
}
}
//存入容器中
beans.put(id,bean);
}
}
}