java中的反射
一、主要使用的类
1.Class类:代表类的定义
-
Class对象的获取方式
- 1.Class clz = Class.forName(“类的完全限定名”);
- 2.Class clz =类名.class ;
- 3.Class clz = 对象.getClass( );
-
常用的方法
- forName(String className)注意参数是全类名(包名+类名)
- newInstance( ) 创建类的实例(对象)
- getName( ) 获得类的完整路径名字
- getSimpleName( ) 获得类的名字
- getPackage( ) 获得类的包
- getSuperclass( ) 获得当前类继承的父类的名字
- getInterfaces( ) 获得当前类实现的类或是接口,注意返回值是Class[]数组
//Person类
package com.my.entity;
public class Person {
public String name;//共有的成员变量filed
public int age;//共有的成员变量
private float weight;//私有的成员变量
private String address;//私有的成员变量
int height;//缺省的成员变量
protected int id;
public Person() {
super();
System.out.println("Person的无参构造函数被调用了");
}
public Person(String name) {
super();
this.name = name;
}
public Person(String name, int age) {
super();
System.out.println("Person的有参构造函数被调用了");
this.name = name;
this.age = age;
System.out.println("name="+name+" "+"age="+age);
}
public Person(String name, int age, float weight, String address, int height, int id) {
super();
this.name = name;
this.age = age;
this.weight = weight;
this.address = address;
this.height = height;
this.id = id;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", address=" + address + ", height="
+ height + ", id=" + id + "]";
}
public void f1( int x,double y,String z)
{
System.out.println("x="+x+"y="+y+"z="+z);
System.out.println("f1函数被调用");
}
}
//这是Person类的结束
//main方法测试一
public static void main(String[] args) {
//1.通过Class.forName("");获取
try {
Class c1=Class.forName("com.my.entity.Person");//注意里面的参数是类的全限定名(包名+类名)
System.out.println(c1);//Class类重写了toString方法所以打印的是class 和全限定名
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//2.通过类名.class获取
Class c2=Person.class;
System.out.println("包名:"+c2.getPackageName());
//3.通过对象.getClass()方法获取
Person person=new Person();
Class c3=person.getClass();
System.out.println("包路径:"+c3.getPackage());
}
//main方法测试二,记得导入Serializable,Cloneable,RandomAccess这几个包
public class Demo02 extends Person implements Serializable,Cloneable,RandomAccess {
public static void main(String[] args) {
try {
//获取Class类对象,注意c1字节码对象表示的是Demo02这个类
Class c1 = Class.forName("com.my.reflection.Demo02");
//创建实例要求Class有一个无参数的构造方法
Object obj1=c1.newInstance();
Object obj2=c1.newInstance();
Object obj3=c1.newInstance();
//System.out.println(obj1.toString());与System.out.println(obj1);等价的
System.out.println(obj1);//执行这句相当于是obj1.toString(),如果没有重写toStrong则默认是用Object的tostring
System.out.println(obj2);
System.out.println(obj3);
//输出完全限定名
System.out.println("完全限定名:"+c1.getName());
System.out.println("简单类名:"+c1.getSimpleName());
//获取父类的字节码对象
Class superClass1=c1.getSuperclass();
System.out.println("Demo02类的父类字节码对象:"+superClass1);
//获取此类的所有的实现接口,返回结果是一个字节码对象的数组
Class []interfaces=c1.getInterfaces();
//注意在输出是用Arrays类的toString方法进行数组的遍历
System.out.println(Arrays.toString(interfaces));
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
}
2.Method类:代表类的方法
-
常用的方法
- getMethod(String name, Class…<?> parameterTypes) 获得该类某个公有的方法 注意里面的…表示的是动态参数,第一个参数表示的是要得到的方法的名字,第二个参数表示的是对应方法参数的字节码类型,返回值为Method
- getMethods( )获得该类所有公有的方法,返回值是Method数组
- getDeclaredMethod(String name, Class…<?> parameterTypes)获得该类某个方法,第一个参数表示的是方法的名字第二个参数表示的对应参数的字节码,返回值为Method
- getDeclaredMethods( )获得该类所有方法,返回值是Method数组
- invoke(Object obj, Object… args) 传递object对象及参数调用该对象对应的方法
- setAccessible(boolean flag) 设置私有方法是否可访问
- getModifiers( ) 返回方法访问修饰符
- getParameters( ) 返回方法参数
- getReturnType( ) 返回返回值类型Class
import java.lang.reflect.Method;
@SuppressWarnings("all")
public class Demo05 {
public static void main(String[] args) {
//寻找Object类中的所有的方法
Class c1=Object.class;
Method[] allMethods=c1.getDeclaredMethods();
for(Method me:allMethods) {
System.out.println(me);
}
//寻找某个特定的方法
// Method m1=c1.getDeclaredMethod(name, parameterTypes)
}
}
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.Arrays;
import com.my.entity.Person;
@SuppressWarnings("all")//忽略所有的警告
public class Demo07 {
public static void main(String[] args) {
System.out.println("============普通方式执行方法的调用=================");
Person person=new Person();
person.f1(23,2.3, "f1函数第一次调用");
//通过反射的方式执行方法
System.out.println("============通过反射的方式执行方法=================");
//1.获取Person类的字节码对象
Class p1=Person.class;
//2.获取Person的实例对象,用Object接收来体现反射
try {
Object object=p1.newInstance();
//3.获取方法的相关信息,一般方法是共有的所以用下面的方法可以执行,而对于私有的方法则需要设置可见性的
Method m1=p1.getMethod("f1",int.class,double.class,String.class);
//4.执行方法的调用
m1.invoke(object, 99,6.39,"f1函数的第二次调用");//后面的参数为传入的参数值
System.out.println("============通过反射的方式输出调用方法的所有信息=================");
System.out.println("方法的名字:"+m1.getName());
System.out.println("方法的访问修饰符:"+m1.getModifiers());///返回值为1表示的是共有的访问权限
System.out.println("方法的返回值类型:"+m1.getReturnType());
Parameter per[]= m1.getParameters();
System.out.println("方法的参数列表:"+Arrays.toString(per));
System.out.println("参数的个数:"+m1.getParameterCount());
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
3.Field类:代表类的成员变量
-
常用的方法
- getField(String name) 获得某个公有的属性对象,返回值是Field,参数是成员变量的名字
- getFields() 获得所有公有的属性对象,注意返回值是Field[]数组
- getDeclaredField(String name) 获得单个属性对象 参数是成员变量的名字,返回值是Field
- getDeclaredFields() 获得所有属性对象 ,返回值是 Field[]数组
- equals(Object obj) 属性与obj相等则返回true
- get(Object obj) 获得obj中对应的属性值
- set(Object obj, Object value)设置obj中对应属性值
- setAccessible(boolean flag)设置私有属性是否可访问
//Person 类
package com.my.entity;
public class Person {
public String name;//共有的成员变量filed
public int age;//共有的成员变量
private float weight;//私有的成员变量
private String address;//私有的成员变量
int height;//缺省的成员变量
protected int id;
public Person() {
super();
System.out.println("Person的无参构造函数被调用了");
}
public Person(String name) {
super();
this.name = name;
}
public Person(String name, int age) {
super();
System.out.println("Person的有参构造函数被调用了");
this.name = name;
this.age = age;
System.out.println("name="+name+" "+"age="+age);
}
public Person(String name, int age, float weight, String address, int height, int id) {
super();
this.name = name;
this.age = age;
this.weight = weight;
this.address = address;
this.height = height;
this.id = id;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", address=" + address + ", height="
+ height + ", id=" + id + "]";
}
public void f1( int x,double y,String z)
{
System.out.println("x="+x+"y="+y+"z="+z);
System.out.println("f1函数被调用");
}
}
//这表示的是忽略所有的警告
@SuppressWarnings("all")
public class Demo03 {
public static void main(String[] args) {
Class c1=Person.class;
//获取所有共有的成员变量
System.out.println("===============所有共有的成员变量==================");
//注意返回值是一个数组
Field []fields1=c1.getFields();
//遍历数组
for(Field f1:fields1) {
System.out.println(f1);
}
//获取所有的成员变量(共有的+私有的+缺省的+保护的)
System.out.println("===============所有的成员变量======================");
Field[]fields2=c1.getDeclaredFields();
//遍历数组
for(Field f2:fields2) {
System.out.println(f2);
}
System.out.println("===============获取单个共有的成员变量======================");
try {
Field f1=c1.getField("name");//里面的参数填写成员变量的名字,这个会报异常,如果找不到成员变量则会抛异常
Field f2=c1.getField("age");//这里面只能填写共有字段而不能是私有的否则会报异常
System.out.println(f1);
System.out.println(f2);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
System.out.println("===============获取单个指定的成员变量======================");
try {
Field f3=c1.getDeclaredField("age");//共有的
Field f4=c1.getDeclaredField("name");//共有的
Field f5=c1.getDeclaredField("weight");//私有的
Field f6=c1.getDeclaredField("address");//私有的
Field f7=c1.getDeclaredField("height");//缺省的
Field f8=c1.getDeclaredField("id");//保护的
System.out.println(f3);
System.out.println(f4);
System.out.println(f5);
System.out.println(f6);
System.out.println(f7);
System.out.println(f8);
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}
4.Constructor类:代表类的构造方法
-
常用的方法
-
newInstance(Object… initargs) 根据传递的参数创建类的对象
-
setAccessible(boolean flag) 设置私有构造方法是否可访问
-
//Person
package com.my.entity;
public class Person {
public String name;//共有的成员变量filed
public int age;//共有的成员变量
private float weight;//私有的成员变量
private String address;//私有的成员变量
int height;//缺省的成员变量
protected int id;
public Person() {
super();
System.out.println("Person的无参构造函数被调用了");
}
public Person(String name) {
super();
this.name = name;
}
public Person(String name, int age) {
super();
System.out.println("Person的有参构造函数被调用了");
this.name = name;
this.age = age;
System.out.println("name="+name+" "+"age="+age);
}
public Person(String name, int age, float weight, String address, int height, int id) {
super();
this.name = name;
this.age = age;
this.weight = weight;
this.address = address;
this.height = height;
this.id = id;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", weight=" + weight + ", address=" + address + ", height="
+ height + ", id=" + id + "]";
}
public void f1( int x,double y,String z)
{
System.out.println("x="+x+"y="+y+"z="+z);
System.out.println("f1函数被调用");
}
}
@SuppressWarnings("all")
public class Demo04 {
public static void main(String[] args) {
Class c1=Person.class;
try {
//获取共有的无参构造函数
Constructor c00=c1.getConstructor();
//获取一个共有的参数构造函数
Constructor c11=c1.getDeclaredConstructor(String.class);
//两个参数的所有构造方法
Constructor c22=c1.getDeclaredConstructor(String.class,int.class);//按照方法参数类型传入参数
System.out.println("无参数构造函数:"+c00);
System.out.println("一个参数构造函数:"+c11);
System.out.println("两个参数构造函数:"+c22);
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}
}
}