目录
目录
1.反射
定义:把一个字节码文件加载到内存中,jvm对该字节码文件解析,创造一个Class对象,把字节码文件中的信息全部存储到Class对象中,使用这个Class对象调用其属性和方法
2.类对象获取
package per.liyue.code.relfect;
public class ReflectMain {
public static void main(String[] args) throws Exception {
/*
* 类的获取
*/
//加载类方式一:forName
Class class1 = Class.forName("per.liyue.code.relfect.Person");
System.out.println("forName加载:" + class1);
//加载类方式二:
Class class2 = Person.class;
System.out.println(".class方式获取:" + class2);
System.out.println("class1 == class2 ?" + (class1==class2));
//加载类方式三:
Person person = new Person();
Class class3 = person.getClass();
System.out.println("getClass方式获取:" + class3);
System.out.println("class1 == class3 ?" + (class1==class3));
}
}
3.构造函数获取
注意公有和私有构造获取区别:
- 私有构造可获取私有构造
- 私有构造获取类自身的构造
package per.liyue.code.reflect;
public class Person {
private String name = null;
private int id = 0;
public Person(){
}
public Person(String name){
this.name = name;
}
private Person(String name, int id){
this.name = name;
this.id = id;
}
//公有函数
public void FunPublic(int num){
System.out.println("这个公有函数的输入值是:" + Integer.toString(num));
}
//私有函数
public void FunPrivate(String concent){
System.out.println("这个私有函数的输入内容是:" + concent);
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "成功构造一个Person对象:name为:" + this.name + "id为:" + this.id;
}
}
package per.liyue.code.reflect;
import java.lang.reflect.Constructor;
public class ReflectGetConstructor {
public static void main(String[] args) throws Exception {
//获取类对象
Class clazz = Class.forName("per.liyue.code.reflect.Person");
//1.公有构造
//1.1获取所有公有构造
Constructor[] constructors = clazz.getConstructors();
for (Constructor constructor : constructors) {
System.out.println(constructor);
}
//1.2获取指定构造
Constructor c = clazz.getConstructor(String.class);
System.out.println(c);
//1.3使用公有构造产生一个对象
Person p = (Person) clazz.newInstance();
System.out.println(p);
//2.私有构造:注意这里会将类私有和公有构造都获取到
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor);
}
//2.1指定私有构造获取
Constructor declaredConstructor = clazz.getDeclaredConstructor(String.class, int.class);
System.out.println(declaredConstructor);
//2.2使用私有构造产生一个对象
//这里直接使用创建对象将报错,因为权限访问限制导致
//Person dP = (Person) declaredConstructor.newInstance("张三", 1);
/*
* 暴力反射
* 这里先将权限打开,后面即可使用私有构造,但是这样的情况下,单例模式是失效的,不过现实中不会这么用!
*/
declaredConstructor.setAccessible(true);
Person dP = (Person) declaredConstructor.newInstance("张三", 1);
}
}
4.函数获取
package per.liyue.code.reflect;
public class Person {
private String name = null;
private int id = 0;
public Person(){
}
public Person(String name){
this.name = name;
}
private Person(String name, int id){
this.name = name;
this.id = id;
}
//公有函数
public void FunPublic(int num){
System.out.println("这个公有函数的输入值是:" + Integer.toString(num));
}
//私有函数
private void FunPrivate(String concent){
System.out.println("这个私有函数的输入内容是:" + concent);
}
//静态函数
public static void FunStatic(int id){
System.out.println("这个静态函数的输入内容是:" + Integer.toString(id));
}
//参数是数组
public void FunArray(int [] array){
System.out.println("这个函数输入数组长度为:" + array.length);
}
//无参函数
public void FunVoid(){
System.out.println("这个函数没有入参");
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "成功构造一个Person对象:name为:" + this.name + "id为:" + this.id;
}
}
package per.liyue.code.reflect;
import java.lang.reflect.Method;
public class ReflectGetMethod {
public static void main(String[] args) throws Exception {
//获取类对象
Class clazz = Class.forName("per.liyue.code.reflect.Person");
Person p = (Person)clazz.newInstance();
//1.获取公有函数
Method[] m = clazz.getMethods();
for(Method method : m){
System.out.println(method);
}
//1.1获取指定公有函数
Method mGet = clazz.getMethod("FunPublic", int.class);
//这里需要对象
mGet.invoke(p, 1);
//2.获取私有函数
Method[] mP = clazz.getDeclaredMethods();
for(Method mp : mP){
System.out.println(mp);
}
//2.1获取指定私有函数
Method mm = clazz.getDeclaredMethod("FunPrivate", String.class);
//这里需要将权限打开才能正确调用
mm.setAccessible(true);
mm.invoke(p, "哈哈");
//这里需要对象
//mGet.invoke(p, 1);
//3.获取数组函数,入参为数组比较特别,需要注意
Method mA = clazz.getDeclaredMethod("FunArray", int[].class);
mA.invoke(p, new int[]{});
//4.获取静态函数:今天函数不需要类对象
Method mS = clazz.getDeclaredMethod("FunStatic", int.class);
mS.invoke(null, 123);
}
}