public Constructor[] getDeclaredConstructors():获取所有的构造方法(包括私有、受保护、默认、公有)
2.获取一个构造器(如果是无参构造器,那么参数写null或者不写)
2.1获取单个 共有的构造器
public Constructor getConstructor(Class ... paramterTypes) ;//获取单个的“公有的”构造方法(参数是构造器参数的类型;注意是构造器参数的类型!)2.2.获取单个任何类型的构造器public Constructor getDeclaredConstructor(Class... parameterTypes):获取"某个构造方法"可以是私有的,或受保护、默认、公有
3.通过构造方法对象来创建对象
Object newInstance(构造器的参数) //构造方法的一个方法,用于创建对象,返回Object类型 需要自己手动的类型转换一下
Student.java
packagecom.kylin.FanShe;public classStudent {private String name; //姓名
private String sex; //性别
private String id; //学号
private int age; //年龄//4种访问类型的构造器 包访问类型 共有 保护 私有
Student(){
System.out.println("包访问类型的构造器");
}//共有
publicStudent(String name){this.name=name;
System.out.println("共有访问类型的构造器,且名字为:"+name);
}public Student(String id, intage){this.id=id;this.age=age;
System.out.println("共有的构造器,id,年龄"+id+" "+age);
}//保护
protectedStudent(String name,String sex){this.name=name;this.sex=sex;
System.out.println("保护类型的构造器,且名字为:"+name+"性别:"+sex);
}//私有
privateStudent(String name,String id,String sex){this.name=name;this.id=id;this.sex=sex;
System.out.println("私有的构造器:"+name+" "+id+" "+sex);
}publicString getName() {returnname;
}public voidsetName(String name) {this.name =name;
}publicString getSex() {returnsex;
}public voidsetSex(String sex) {this.sex =sex;
}publicString getId() {returnid;
}public voidsetId(String id) {this.id =id;
}public intgetAge() {returnage;
}public void setAge(intage) {this.age =age;
}
}
获取构造方法代码: (一开始引入了:import java.lang.reflect.Constructor)
public static void main(String []args) throwsClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取class对象
Class clazz=Class.forName("com.kylin.FanShe.Student");//1.1获取所有的公有的构造器
Constructor []constructors=clazz.getConstructors();for(Constructor constructor:constructors){
System.out.println(constructor);
}/** 结果:
* public com.kylin.FanShe.Student(java.lang.String,int)
public com.kylin.FanShe.Student(java.lang.String)
**/System.out.println("-----------------------------美丽的分割线-------------------------------");//1.2获取所有任何类型的构造方法
Constructor []allConstructors=clazz.getDeclaredConstructors();for(Constructor constructor:allConstructors){
System.out.println(constructor);
}/** 结果:
* private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String)
protected com.kylin.FanShe.Student(java.lang.String,java.lang.String)
public com.kylin.FanShe.Student(java.lang.String,int)
public com.kylin.FanShe.Student(java.lang.String)
com.kylin.FanShe.Student()*/System.out.println("-----------------------------美丽的分割线-------------------------------");//2.1获取某个公有的 构造器
Constructor myPubConstructor=clazz.getConstructor(String.class); //参数是:构造器参数的类型
System.out.println(myPubConstructor);//输出:public com.kylin.FanShe.Student(java.lang.String)
System.out.println("-----------------------------美丽的分割线-------------------------------");//2.2获取某个任何类型的构造器
Constructor myEveConstructor=clazz.getDeclaredConstructor(String.class,String.class,String.class);
System.out.println(myEveConstructor);//输出:private com.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String)//通过构造方法来创建对象
Student student= (Student) myPubConstructor.newInstance("name");
System.out.println(student.getName());//这样会抛出异常,因为一个私有的构造器不能被用来创建对象 所以需要设置访问权限//Student student1= (Student) myEveConstructor.newInstance("1","22","333");//System.out.println(student1.getName()+" "+student1.getId()+" "+student1.getSex());
myEveConstructor.setAccessible(true);//暴力访问
Student student1= (Student) myEveConstructor.newInstance("111","222","333");
System.out.println(student1.getName()+" "+student1.getSex()+" "+student1.getId());
}
输出结果:
public com.kylin.FanShe.Student(java.lang.String,int)publiccom.kylin.FanShe.Student(java.lang.String)-----------------------------美丽的分割线-------------------------------
privatecom.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String)protectedcom.kylin.FanShe.Student(java.lang.String,java.lang.String)public com.kylin.FanShe.Student(java.lang.String,int)publiccom.kylin.FanShe.Student(java.lang.String)
com.kylin.FanShe.Student()-----------------------------美丽的分割线-------------------------------
publiccom.kylin.FanShe.Student(java.lang.String)-----------------------------美丽的分割线-------------------------------
privatecom.kylin.FanShe.Student(java.lang.String,java.lang.String,java.lang.String)
共有访问类型的构造器,且名字为:name
name
私有的构造器:111 222 333
111 333 222
五,通过class对象获取成员变量并调用
teacher.java
packagecom.kylin.FanShe;public classTeacher {publicString name;publicString name1;
String school;protectedString sex;private intage;publicTeacher(){
}
@OverridepublicString toString(){return "Teacher[name="+name+",school=" +school+
",sex="+sex+",age="+age+",name1="+name1;
}
}
测试获取成员变量并且调用
packagecom.kylin.FanShe;importorg.junit.Test;importjava.lang.reflect.Field;importjava.lang.reflect.InvocationTargetException;//获取成员变量
public classGetFiled {/** 获取成员变量并调用:
*
* 1.批量的
* 1).Field[] getFields():获取所有的"公有字段"
* 2).Field[] getDeclaredFields():获取所有字段,包括:私有、受保护、默认、公有;
* 2.获取单个的:
* 1).public Field getField(String fieldName):获取某个"公有的"字段;
* 2).public Field getDeclaredField(String fieldName):获取某个字段(可以是私有的)
*
* 设置字段的值:
* Field --> public void set(Object obj,Object value):
* 参数说明:
* 1.obj:要设置的字段所在的对象;
* 2.value:要为字段设置的值*/
public static void main(String []args) throwsClassNotFoundException, NoSuchFieldException,
NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {//获取class对象
Class clazz=Class.forName("com.kylin.FanShe.Teacher");//获取所有的共有的属性
Field []fields=clazz.getFields();for(Field field:fields){
System.out.println(field);
}
System.out.println("-----------------------------美丽分割线-------------------------");//获取所有的属性 (任何访问类型)
Field []allFields=clazz.getDeclaredFields();for(Field field:allFields){
System.out.println(field);//这也是一个对象来的
}
System.out.println("-----------------------------美丽分割线-------------------------");//获取指定的共有属性并且赋值给对象
Field nameField=clazz.getField("name");
System.out.println(nameField);
Teacher teacher= (Teacher) clazz.getConstructor(null).newInstance();
nameField.set(teacher,"苏桃");
System.out.println(teacher);
System.out.println("-----------------------------美丽分割线-------------------------");//获取指定的任何类型(这里获取私有来测试)的属性 并且赋值给对象
Field priAgeField=clazz.getDeclaredField("age"); //女人的年龄是秘密嘛
System.out.println(priAgeField);//私有的需要设置权限 这里是暴力访问
priAgeField.setAccessible(true);
priAgeField.set(teacher,20);
System.out.println(teacher);
}
}
输出:
publicjava.lang.String com.kylin.FanShe.Teacher.namepublicjava.lang.String com.kylin.FanShe.Teacher.name1-----------------------------美丽分割线-------------------------
publicjava.lang.String com.kylin.FanShe.Teacher.namepublicjava.lang.String com.kylin.FanShe.Teacher.name1
java.lang.String com.kylin.FanShe.Teacher.schoolprotectedjava.lang.String com.kylin.FanShe.Teacher.sexprivate intcom.kylin.FanShe.Teacher.age-----------------------------美丽分割线-------------------------
publicjava.lang.String com.kylin.FanShe.Teacher.name
Teacher[name=苏桃,school=null,sex=null,age=0,name1=null
-----------------------------美丽分割线-------------------------
private intcom.kylin.FanShe.Teacher.age
Teacher[name=苏桃,school=null,sex=null,age=20,name1=null
六,使用class对象获取成员方法并且调用(调用肯定得是该类型的对象或者子类才可以调用)
people.java
packagecom.kylin.FanShe;public classPeople {public voidshow1(String s){
System.out.println("调用了:公有的,String参数的show1(): s = " +s);
}protected voidshow2(){
System.out.println("调用了:受保护的,无参的show2()");
}voidshow3(){
System.out.println("调用了:默认的,无参的show3()");
}private String show4(intage) {
System.out.println("调用了,私有的,并且有返回值的,int参数的show4(): age = " +age);return "abcd";
}
}
获取成员方法并且调用
/*获取成员方法并调用
* 1.批量的:
* public Method[] getMethods():获取所有"公有方法";(包含了父类的方法也包含Object类)
* public Method[] getDeclaredMethods():获取所有的成员方法,包括私有的(不包括继承的)
2.获取单个的:
* public Method getMethod(String name,Class>... parameterTypes):
* 参数:
* name : 方法名;
* Class ... : 形参的Class类型对象
public Method getDeclaredMethod(String name,Class>... parameterTypes)
* 调用方法:
* Method --> public Object invoke(Object obj,Object... args):
* 参数说明:
* obj : 要调用方法的对象,这个对象一定要是和方法同一类/或者子类也应该可以的;
* args:调用方式时所传递的实参;
):*/
public static void main(String[] args) throwsException {//1.获取Class对象
Class clazz = Class.forName("com.kylin.FanShe.People");//2.获取所有公有方法
System.out.println("***************获取所有的”公有“方法*******************");
Method[] methodArray=clazz.getMethods();for(Method m : methodArray) {
System.out.println(m);
}
System.out.println("***************获取所有的方法,包括私有的*******************");
methodArray=clazz.getDeclaredMethods();for(Method m : methodArray) {
System.out.println(m);
}
System.out.println("***************获取公有的show1()方法*******************");
Method pubMethod= clazz.getMethod("show1", String.class);
System.out.println(pubMethod);//实例化一个Student对象
People people=(People) clazz.getConstructor().newInstance();
pubMethod.invoke(people,"刘德华"); //方法对象被调用执行,则输出了那句话
System.out.println("***************获取私有的show4()方法******************");
Method priMethod= clazz.getDeclaredMethod("show4", int.class);
System.out.println(priMethod);
priMethod.setAccessible(true);//解除私有限定
System.out.println("11111111111111111111111");//抛出异常 可能是得该类的对象才可以调用//Object object=new Object();
People people1=(People) clazz.getConstructor().newInstance();
priMethod.invoke(people1,20);//需要两个参数,一个是要调用的对象(获取有反射),一个是实参//System.out.println("返回值:" + result);
}
总结:
反射可以获取到一个类的所有的东西——静态的非静态的,私有的公有的……只要是在类中的,或者继承于父类的东西,都可以被获取成一个对象,然后进行调用……当然也可以获取main方法等等,这里主要介绍了通过类的字节码对象获取构造方法,成员变量,方法等……反射同时也是很多框架实现的基础,要好好琢磨……