反射:
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象.
获取Class对象的三种方式:
方式一:Object-->getClass()方法,获取它的Class对象
方式二:任何的数据类型,都有一个静态的class属性,可以直接访问;
方式三:(常用)Class-->static forName():能够获取一个class对象
获取类的构造方法,并调用;
public Constructor[] getConstructors():获取所有的公有构造方法
public Constructor[] getDeclaredConstructors():获取所有构造方法,包括公有、私有、受保护、默认
public Constructor<T> getConstructor(Class<?>... parameterTypes):获取单个的公有的构造方法;
public Constructor getDeclaredConstructor(Class<?>... parameterTypes):获取单个的构造方法,包括 私有的。
实例:
public class Student {
}
public class Demo {
public static void main(String[] args) throws Exception {
Class stuClass = Class.forName("com.itcast.demo02_获取构造方法并调用.Student");
//1.获取所有公共构造方法
System.out.println("***********所有的公共构造方法************");
Constructor[] conArray = stuClass.getConstructors();
for(Constructor c : conArray){
System.out.println(c);
}
//2.获取所有构造方法;
System.out.println("**********获取所有的构造方法,包括私有*************");
Constructor[] conArray2 = stuClass.getDeclaredConstructors();
for(Constructor c : conArray2){
System.out.println(c);
}
//3.获取单个的公有构造方法:
System.out.println("************获取单个的公有构造方法****************");
Constructor con1 = stuClass.getConstructor(String.class);
System.out.println(con1);
con1 = stuClass.getConstructor(float.class);
System.out.println(con1);
//调用一个公有的,带参的构造方法;
Object obj = con1.newInstance(2.0F);
//4.获取单个的私有构造方法:
System.out.println("***********获取单个的私有的构造方法*****************");
Constructor con2 = stuClass.getDeclaredConstructor();
System.out.println(con2);
con2.setAccessible(true);//强制访问私有成员,暴力访问
//调用私有,无参的构造方法
Object obj2 = con2.newInstance();
System.out.println("***********获取单个的默认的构造方法*****************");
Constructor con3 = stuClass.getDeclaredConstructor(int.class);
System.out.println(con3);
}
}
获取成员属性:
1.Field[] getFields():获取所有的公共成员属性;
2.Field[] getDeclaredFields():获取所有的成员属性,包括私有,默认,受保护
3.Field getFiled(String name):获取某个公有的成员属性;name:字段名称
4.Field getDeclaredFiled():获取某个成员属性。包括私有,默认,受保护
为属性赋值:
Field--> set(Object obj,Object value):
参数:
obj:此类的对象;
value:属性值
public Object get(Object obj)
实例:
public class Student {
//*********构造方法*********//
private Student(){
System.out.println("调用了私有构造方法");
}
Student(int a){
System.out.println("调用了默认的构造方法,int a = " + a);
}
protected Student(char c){
System.out.println("调用了受保护的构造方法,char c = " + c);
}
public Student(String s){
System.out.println("调用了公有的构造方法,String s = " + s);
}
public Student(float f){
System.out.println("调用了公有的构造方法,float f = " + f);
}
//***************成员属性********************//
private String name;//私有
int age;//默认
protected char sex;//受保护
public double score;//公有的
}
public class Demo {
public static void main(String[] args) throws Exception{
Class stuClass = Class.forName("com.itcast.demo03_获取成员属性.Student");
//1.Field[] getFields()
System.out.println("******************获取所有的公有成员属性***********");
Field[] fieldArray = stuClass.getFields();
for(Field f : fieldArray){
System.out.println(f);
}
System.out.println("************获取所有成员属性,包括私有**************");
Field[] fieldArray2 = stuClass.getDeclaredFields();
for(Field f : fieldArray2){
System.out.println(f);
}
System.out.println("*********获取某个公有的成员属性**********************");
Field field = stuClass.getField("score");
System.out.println(field);
System.out.println("*********获取某个成员属性,包括私有,默认,受保护**********");
Field field2 = stuClass.getDeclaredField("name");
System.out.println(field2);
Field field3 = stuClass.getDeclaredField("age");
System.out.println(field3);
Constructor con = stuClass.getConstructor(String.class);//获取公有的,String参数的构造方法
Object obj = con.newInstance("张三");//调用构造方法,并传递参数
System.out.println("*********为公有成员属性赋值****************");
field.set(obj, 80.0);
System.out.println(field.get(obj));
System.out.println("*********为私有成员属性赋值****************");
field2.setAccessible(true);//访问私有的,设定暴力访问
field2.set(obj, "李四");
System.out.println(field2.get(obj));
}
}
获取成员方法:
1.Method[] getMethods():获取所有公有的成员方法;
2.Method[] getDeclaredMethods():获取所有的成员方法,包括私有,默认,受保护;
3.Method getMethod():获取某个公有的方法;
4.Method getDeclaredMethod():获取某个方法,包括私有,默认,受保护
调用方法:
Method:
invoke(Object obj,Object param):
实例:
public class Student {
//*********构造方法*********//
private Student(){
System.out.println("调用了私有构造方法");
}
Student(int a){
System.out.println("调用了默认的构造方法,int a = " + a);
}
protected Student(char c){
System.out.println("调用了受保护的构造方法,char c = " + c);
}
public Student(String s){
System.out.println("调用了公有的构造方法,String s = " + s);
}
public Student(float f){
System.out.println("调用了公有的构造方法,float f = " + f);
}
//***************成员属性********************//
private String name;//私有
int age;//默认
protected char sex;//受保护
public double score;//公有的
//*************成员方法***************//
private void show(){
System.out.println("调用了-->private show()");
}
void show(int a){
System.out.println("调用了 --> 默认 show() int a = " + a);
}
protected void show(char c){
System.out.println("调用了 --> 受保护show() char c = " + c);
}
public void show(String s){
System.out.println("调用了 --> 公有的show() String s = " + s);
}
public int sum(int a,int b){
return a + b;
}
}
public class Demo {
public static void main(String[] args) throws Exception {
Class stuClass = Class.forName("com.itcast.demo04_获取成员方法.Student");
System.out.println("********获取所有公共的成员方法*********");
Method[] mArray = stuClass.getMethods();//包含了父类中公有的成员方法;
for(Method m : mArray){
System.out.println(m);
}
System.out.println("*********获取所有的成员方法,包括私有,默认,受保护的*********");
Method[] mArray2 = stuClass.getDeclaredMethods();//不包含父类的;
for(Method m : mArray2){
System.out.println(m);
}
System.out.println("*********获取某个公有成员方法*****************");
Method m = stuClass.getMethod("show", String.class);
Object obj = stuClass.getConstructor(float.class).newInstance(2.0F);
//调用公有方法;
m.invoke(obj, "张三");//调用m所代表的方法,show(String s)
System.out.println("*********获取私有方法******************");
Method m2 = stuClass.getDeclaredMethod("show");
m2.setAccessible(true);//调用私有方法,先暴力访问
//调用方法
m2.invoke(obj);
System.out.println("*********调用带返回值的方法***********");
Method m3 = stuClass.getMethod("sum", int.class,int.class);
Object result = m3.invoke(obj, 20,30);
System.out.println("返回值为:" + result);
}
}