* 面试题:
* 如何获取类的字节码文件对象,并且有几种方式呢?
*
*1)Object类中的getClass()方法,表示正在运行的那个类:Class类
*2)数据类型的class属性 举例:String.class,Student.class
*3)Class类中的特有方法:forName(String className):(重点,数据库加载驱动:Drivers)
* public static Class<?> forName(String className):获取字节码文件对象
*
* 开发中常使用的方式,因为第三种里面的参数是一个字符串...,字符串的内容是一个类的全路径名称
*
package myReflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class MyReflect1 {
public static void main(String[] args) throws Exception {
Person p1=new Person("黛黛",21,"女");
Class c1=p1.getClass();
System.out.println(c1);
Class c11=p1.getClass();
System.out.println(c11);
Class c12=Class.forName("myReflect.Person");
System.out.println(c11);
Constructor con=c1.getDeclaredConstructor(String.class);
con.setAccessible(true);
Object obj=con.newInstance("小馒头");
System.out.println(obj);
Field agef=c1.getDeclaredField("age");
agef.set(obj,21);
Field sexf=c1.getDeclaredField("sex");
sexf.set(obj,"女");
System.out.println(obj);
Class c2=Class.forName("myReflect.Person");
Constructor con2=c2.getDeclaredConstructor(String.class);
con2.setAccessible(true);
Object obj2=con2.newInstance("煎饼果果");
Method mAge=c2.getMethod("setAge",int.class);
Object obj3=mAge.invoke(obj2,22);
System.out.println(obj3);
Method mSex=c2.getDeclaredMethod("setSex",String.class);
mSex.invoke(obj2,"男");
System.out.println(obj2);
}
}
应用:
1)设置动态代理
package org.westos.reflect_handler2;
import java.lang.reflect.Proxy;
/**
*测试类
* @author Apple
*/
public class Test {
public static void main(String[] args) {
UserDao ud = new UserDaoImpl() ;
ud.add() ;
ud.delete();
ud.update() ;
ud.serach() ;
System.out.println("------------------");
MyInvocationHandler handler = new MyInvocationHandler(ud) ;
UserDao proxy = (UserDao) Proxy.newProxyInstance(ud.getClass().getClassLoader(),
ud.getClass().getInterfaces(),handler) ;
proxy.add();
proxy.delete() ;
proxy.update() ;
proxy.serach() ;
}
}
package org.westos.reflect_handler2;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
public class MyInvocationHandler implements InvocationHandler {
private Object target ;
public MyInvocationHandler(Object target){
this.target = target ;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable {
System.out.println("权限校验");
Object result = method.invoke(target, args) ;
System.out.println("日志记录");
return result;
}
}
package org.westos.reflect_handler2;
/**
* 用户操作的接口
* @author Apple
*/
public interface UserDao {
public abstract void add() ;
public abstract void delete() ;
public abstract void update() ;
public abstract void serach() ;
}
package org.westos.reflect_handler2;
public class UserDaoImpl implements UserDao {
@Override
public void add() {
System.out.println("增加功能");
}
@Override
public void delete() {
System.out.println("删除功能");
}
@Override
public void update() {
System.out.println("修改功能");
}
@Override
public void serach() {
System.out.println("查询功能");
}
}
2)给你ArrayList<Integer>的一个对象,我想在这个集合中添加一个字符串数据
package myReflect;
import java.lang.reflect.Method;
import java.util.ArrayList;
/**
* 给你ArrayList<Integer>的一个对象,我想在这个集合中添加一个字符串数据,如何实现呢?
*
* 反射的应用:
* 1)在集合中应用
* 2)用来反射区读取配置文件来加载里面的内容(MySQL,Oracle等等,SQLServer,MangoDB)
* @author Apple
*/
public class ArrayListTest {
public static void main(String[] args) throws Exception {
ArrayList<Integer> al=new ArrayList<Integer>();
Class c=al.getClass();
Method m=c.getDeclaredMethod("add",Object.class);
m.invoke(al,"不如");
m.invoke(al,"去死");
for(Object o:al) {
System.out.println(o);
/**
* 不如
* 去死
*/
}
}
}
3)写一个方法,
public void setProperty(Object obj, String propertyName, Object value){},
此方法可将obj对象中名为propertyName的属性的值设置为value
package myReflect;
import java.lang.reflect.Field;
public class Tool {
public void setProperty(Object obj, String propertyName, Object value) throws
NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException{
Class c = obj.getClass() ;
Field field = c.getDeclaredField(propertyName) ;
field.setAccessible(true) ;
field.set(obj, value) ;
}
}
package myReflect;
/**
* 1:写一个方法,
public void setProperty(Object obj, String propertyName, Object value){},
此方法可将obj对象中名为propertyName的属性的值设置为value
* @author Apple
*/
public class ToolDemo {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException,
IllegalArgumentException,
IllegalAccessException {
Person p = new Person() ;
Tool t = new Tool() ;
t.setProperty(p, "name", "高圆圆") ;
t.setProperty(p, "age", 27) ;
System.out.println(p);
Dog d = new Dog() ;
t.setProperty(d, "gender",'公' ) ;
t.setProperty(d, "price", 34.56F) ;
System.out.println(d);
}
}
class Dog{
char gender ;
float price ;
@Override
public String toString() {
return gender+"---"+price ;
}
}
4)用作配置文件,需要时修改文件内容即可
package myReflect;
import java.io.FileReader;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws Exception {
Properties prop = new Properties() ;
prop.setProperty("className","myReflect.Worker");
prop.setProperty("methodName","love");
prop.store(new FileWriter("class.txt"),"Content");
FileReader fr = new FileReader("class.txt") ;
prop.load(fr) ;
fr.close() ;
String className = prop.getProperty("className") ;
String methodName = prop.getProperty("methodName") ;
Class c = Class.forName(className);
Constructor con = c.getConstructor() ;
Object obj = con.newInstance() ;
Method m = c.getMethod(methodName) ;
m.invoke(obj) ;
}
}
---------------------------------------------------------------------------------------------------------------------------------
class.txt
#Content
#Sun Dec 17 16:15:57 CST 2017
methodName=love
className=myReflect.Worker
-----------------------------------------------------------------------------------------------------------------------------------
package myReflect;
public class Student {
public void love(){
System.out.println("学生爱学习,爱Java");
}
}
package myReflect;
public class Worker {
public void love(){
System.out.println("工人爱生活,爱老婆");
}
}