1、反射:
反射有什么用呢?通过反射,我们可以在程序运行的时候动态的创建对象,并且获取某个类中的所有属性、所有方法。
可能你还是有些糊涂,反射具体有什么用?
假设一下这个场景,我们编写一个程序,用户可以输入类名和方法名,然后程序会自动创建对象并执行对应的方法。实际上就是动态的创建对象和动态的执行方法,这是传统的new 对象方式办不到的事情,只能通过反射来解决。
框架类的配置文件的开发方式就是依赖于反射机制
2、反射详解
class User{
private String name;
protected int age;
public boolean sex;
public User(){
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", sex=" + sex +
'}';
}
public User(String name, int age){
this.name = name;
this.age = age;
}
protected User(int age){
this.age = age;
}
private User(int age,boolean sex){
this.age = age;
this.sex = sex;
}
public void printPublic(){
System.out.println(name+"***"+age);
}
void printDefault(){
System.out.println(sex);
}
void printDefault(int a){
System.out.println(a);
}
public static void testStatic(String msg){
System.out.println(msg);
}
private void printPrivate(String name,int age){
System.out.println(name+"***"+age);
}
}
2.1、获取Class对象
class对象是字节码对应的内存结构,记录了类中的所有信息,也是反射获取信息的基本对象
class c = Class.forName(“类的全限定名”);
2.2、获取构造方法
1、Constructor[] c = c.getDeclaredConstructors();
获取类中声明的构造器数组,包括public、private、protected和缺省。
2、Constructor[] c = c.getConstructors();
获取类中构造器数组,只含有public的。
3、Constructor c = c.getConstrutor(int.class,String.class);
获取形参为int和String的构造函数。
2.3、获取方法:
1、Method[] m = c.getDeclaredMethods();
获取类中声明的方法,包括public、private、protected和缺省
2、Method[] m = c.getMethods();
获取类中的方法(包括父类中的方法),只包括public
3、Method m = c.getMethod(“print”,int.class);
从类中的方法通过方法名字和形参类型来获取对应的方法
4、Method m = c.getDeclaredMethod(“print”,String.class);
从声明的方法中通过方法名字和形参类型来获取类中声明的方法
2.4、获取属性
1、Field[] f = c.getFields();
获取类中的属性(包括父类中的public属性),只包括public
2、Field[] f = c.getDeclaredFields();
获取类中声明的属性,包括public、protected、private和缺省
3、Field f = c.getField(“name”);
通过属性名字来获取属性
4、Field f = c.getDeclaredField(“name”);
通过属性名字来获取类中声明的属性
2.5、创建对象
可以通过构造方法来创建对象。
1、public的Constructor
Constructor publicCon = c.getConstructor(String.class,int.class);
User publicUser = (User) publicCon.newInstance(“jay”,33);
2、非public的Constructor
Constructor privateCon = getDeclaredConstructor(int.class,boolean.class);
privateCon.setAccessible(true);
User privateUser = (User)privateCon.newInstance(666,true);
需要额外设置setAccessible(true)来设置构造器对象的访问权限为true
2.6、执行方法
1、利用创建的对象来调用对应API
Class c = Class.forName(“xx.User”);
Constructor con = c.getConstructor();
User u = (User)con.newInstance();
u.printPublic();
2、通过Method对象来调用
Class c = Class.forName(“xx.User”);
Method m = c.getDeclaredMethod(“printPrivate”,String.class,int.class);
m.setAccessible(true);
m.invoke(con,“jaychou”,23);
3、通过反射可以越过泛型检查
List list = new ArrayList();
list.add(“jaychou”);
Class c2 = list.getClass();
Method m = c2.getMethod(“add”,Object.class);
m.invoke(list,1);
for(Object o:list){
System.out.println(o);
}