反射
【1】反射的定义:
在运行期间可以获取对象的类型,类型的方法,类型的属性,类型的构造方法等,让对象可以认识到自身的结构。
【2】方法:
(1)获取对象的类型(获取类对象)
- 方法1:Object.getClass()(返回类型包括类名包名等)
- 方法2:Class.forName("类名)(和方法一的返回类型一致)
- 方法3:类名.class()
//反射 //【1】获取对象的类型(类对象) //方法1:Objetc.getclass() System.out.println(new User().getClass()); //class Reflect.User //方法2:Class.forName("类名"); System.out.println(Class.forName("Reflect.User")); //抛异常//class Reflect.User //这里注意要填写的类名包括包名 //放法3:类名.Class() System.out.println(User.class); //class Reflect.User //这里要注意的是,class不大写 //注意:以上无论用哪种方式所获得的对象都是同一份信息,这个类型的信息 在JVM中仅存在一份
注意:以上无论用哪种方式所获得的对象都是同一份信息,这个类型的信息 在JVM中仅存在一份
(2)类对象的功能
功能1:用反射的方式来创建对象
方法:类对象.newInstance()
这里用一般正常创建对象的方式和用反射来创建对象两种方式做个对比,让读者能更清晰的来了解反射
//【2】类对象的功能
//1:用反射的方式创建对象
//首先是用正常的new 的方式来创建对象
User user = new User();
//用反射的方式,来创建对象 方法:类对象.newInstance();//创建一个新实例(新对象)
User user1 = new User().getClass().newInstance();//抛异常
System.out.println(user1);//Reflect.User@1540e19d
User user2 = (User)Class.forName("Reflect.User").newInstance();
System.out.println(user2);//Reflect.User@677327b6
User user3 = User.class.newInstance();
System.out.println(user3);//Reflect.User@14ae5a5
// 这里注意:用newInstance的时候有两个限制:A:要求类必须有空参构造
// B:要求构造方法不能私有
这里注意:用newInstance的时候有两个限制:A:要求类必须有空参构造
B:要求构造方法不能私有
功能2:用反射的方式来获取方法信息
方法:
(1)类对象.getMethod();获取本类的所有公共方法(public),包括继承的。
(2)类对象.DeclaredMethods();获取本类的所有方法(包括private,protected,public),不包括继承的方法。
(3)类对象.Method(方法名,参数类型);找公共方法,包括继承的,注意==此处的参数类型要填(类型.class)==比如是String类型,就填String.class,没有参数的话,就不填。
(4)类对象.DeclaredMethod(方法名,参数类型);找本类的,不包括继承的方法。
//2:用反射的方式来获取方法信息
Method[] methods = User.class.getMethods();//返回的是User类中所有的公共方法,包括所继承的
for (Method m: methods
) {
System.out.println(m);
}
//运行结果:
// public java.lang.String Reflect.User.getName()
// public void Reflect.User.setName(java.lang.String)
// public java.lang.String Reflect.User.getLocal()
// public void Reflect.User.setAge(int)
// public int Reflect.User.getAge()
// public void Reflect.User.setLocal(java.lang.String)
// public final void java.lang.Object.wait() throws java.lang.InterruptedException
// public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
// public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
// public boolean java.lang.Object.equals(java.lang.Object)
// public java.lang.String java.lang.Object.toString()
// public native int java.lang.Object.hashCode()
// public final native java.lang.Class java.lang.Object.getClass()
// public final native void java.lang.Object.notify()
// public final native void java.lang.Object.notifyAll()
System.out.println("---------------------------------------");
Method[] methods1 = User.class.getDeclaredMethods();//返回的是User类中所有的方法(包括private,protected,public),不包括所继承的
for (Method m1:methods1
) {
System.out.println(m1);
}
//运行结果:
// public java.lang.String Reflect.User.getName()
// public void Reflect.User.setName(java.lang.String)
// public java.lang.String Reflect.User.getLocal()
// public void Reflect.User.setAge(int)
// public int Reflect.User.getAge()
// public void Reflect.User.setLocal(java.lang.String)
System.out.println("---------------------------------------");
System.out.println(User.class.getMethod("getAge"));
System.out.println(User.class.getDeclaredMethod("setLocal", String.class));
//运行结果:
// public int Reflect.User.getAge()
// public void Reflect.User.setLocal(java.lang.String)
功能3 :用反射的方法获取属性信息
方法:
(1)类对象.getFields();//获取所有属性(包括继承的)
(2)类对象.getDeclaresField();//获取本类所有属性,不包括继承的
(3)类对象.getField(“属性名”);
(4)类对象.getDeclaredField(“属性名”);
//(1)类对象.getFields();//获取所有属性(包括继承的)
Field[] fields = User.class.getFields();
for (Field f:fields
) {
System.out.println(f);
}
//(2)类对象.getDeclaresField();//获取本类所有属性,不包括继承的
//(3)类对象.getField(“属性名”);
//(4)类对象.getDeclaredField("属性名");
功能4:用反射的方法获取构造方法
方法:获取构造方法
(1)类对象.getConstractors();//获取所有的公共的构造方法
(2)类对象.getDeclaredConstractor();//获取本类的构造方法
(3)类对象.getConstractor(int.class);
(4)类方案.getDecclaredConstractor(int.class);
Constructor<?>[] constructors = User.class.getConstructors();
for (int i = 0; i < constructors.length; i++) {
System.out.println("Constractors:"+constructors[i]);//所有的构造方法
//Constractors:public Reflect.User()
//Constractors:public Reflect.User(int)
}
Constructor<?>[] declaredConstructors = User.class.getDeclaredConstructors();
for (int i = 0; i < declaredConstructors.length; i++) {
System.out.println("DeclaredConstractors:"+declaredConstructors[i]);//本类内的构造
//DeclaredConstractors:public Reflect.User()
//DeclaredConstractors:public Reflect.User(int)
}
Constructor<User> constructor = User.class.getConstructor(int.class);
System.out.println("Constractor:"+constructor);//Constractor:public Reflect.User(int)
Constructor<User> declaredConstructor = User.class.getDeclaredConstructor(int.class);
System.out.println("DeclaredConstractor:"+declaredConstructor);//DeclaredConstractor:public Reflect.User(int)
功能5:用反射调用方法
正常调用方法:对象.方法名(参数)
反射调用方法:方法.invoke(对象.参数)
User u = new User();
Method getAge = User.class.getDeclaredMethod("getAge");
getAge.setAccessible(true);//调用这个方法可以被访问,可以突破访修饰符的限制
getAge.invoke(u);//抛异常//反射调用方法(性能较低)
//反射调用public void setName(String name)
Method setName = User.class.getDeclaredMethod("setName", String.class);
setName.invoke(u,"张三");
//反射调用私有构造
Method getLocal = User.class.getDeclaredMethod("getLocal");
getLocal.setAccessible(true);
getLocal.invoke(u);
//反射调用构造方法
Constructor<Student> dc1 = Student.class.getDeclaredConstructor();
dc1.setAccessible(true);
Student stu = dc1.newInstance();
System.out.println(stu);
//Reflect.Student@135fbaa4
这里 反射调用的是invoke()方法,