一、概述1.1、概述
反射的概念:
在java中的反射机制是指在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;
对于任意一个对象,都能够调用它的任意一个方法;
这种动态获取信息以及动态调用对象方法的功能称为Java语言的反射机制
二、反射的3种方式2.1、3种方式
1.声明对象如Person p=new Person,通过对象的p.getClass()方法
2.每个类都有一个.class属性,通过Person.class属性
3.Class.fromName("类的全路径"),全路径包名.类名
2.2、示例
普通的JAVA类,经过了一些修改有私有的方法与公有的方法
packagecom.pb.entity;publicclassPerson
{PRivateString name;//姓名privateString gender;//性别privateintage;//年龄publicPerson()
{//公开无参数构造方法System.out.println("公开无参数构造方法");
}publicPerson(String name,String gender,intage)
{//公开有参数构造方法System.out.println("公开有参数构造方法");this.name=name;this.gender=gender;this.age=age;
}//私有构造方法privatePerson(String name)
{
System.out.println("这是私有的只有name的构造方法:"+name);
}//私有构造方法privatePerson(String name,intage)
{
System.out.println("这是私有的只有name和age的构造方法:"+name+"...."+age);
}/*getter、setter方法*/publicvoidsetName(String name)
{this.name=name;
}publicString getName()
{returnthis.name;
}publicvoidsetGender(String gender)
{this.gender=gender;
}publicString getGender()
{returnthis.gender;
}/*静态方法*/publicstaticvoidstaticMethod()
{
System.out.println("这是一个staticMethod方法");
}/*私有化方法*/privatevoidsetAge(intage)
{this.age=age;
}privateintgetAge()
{returnthis.age;
}/*私有的方法*/privatevoidtest()
{
System.out.println("这是私有的test方法");
}/*私有的方法*/privatevoidtest(String name,String gender)
{
System.out.println("这是私有的有参数的方法"+name+"..."+gender);
}/*自我介绍的方法*/publicvoidshow()
{
System.out.println("姓名:"+this.name+",性别:"+this.gender+",年龄:"+this.age);
}
}
测试类
packagecom.pb.demo1;//导入类importcom.pb.entity.Person;/*反射的三种方式:
1.类.class
2.声明对象,对象.getClass()方法如Person p=new Person(); p.getClass();
3.Class.forName("类的全路径");*/classReflectionDemo1
{publicstaticvoidmain(String[] args)throwsException
{
reflect_fun1();
System.out.println("=========================");
reflect_fun2();
System.out.println("=========================");
reflect_fun3();
System.out.println("=========================");
}/*类.class*/publicstaticvoidreflect_fun1()
{//获取类对象,得到一个Class对象Class cla1=Person.class;
Class cla2=Person.class;
System.out.println(cla1==cla2);
}/*声明对象,对象.getClass()方法如Person p=new Person(); p.getClass();*/publicstaticvoidreflect_fun2()
{
Person p1=newPerson();//通过对象的getClass()方法Class cla1=p1.getClass();
Person p2=newPerson();
Class cla2=p2.getClass();
System.out.println(cla1==cla2);
}/*Class.forName("类的全路径");*/publicstaticvoidreflect_fun3()throwsException
{
Class cla1=Class.forName("com.pb.entity.Person");
System.out.println(cla1);
}
}
三、获取构造方法、方法、属性3.1、概述
构造方法:
公开的指定:getConstructor("方法名",参数1.....参数n),如String.class,要与方法中顺序一至,没有参数可以不写所有公开:getConstructors();返回一个Constructor [] 数组所有:getDeclaredConstructors();返回一个Constructor [] 数组私有:getDeclaredConstructor("方法名",参数1.....参数n),方法:
公开的指定:getMethod("方法名",参数1.....参数n),如String.class,要与方法中顺序一至,没有参数可以不写所有公开:getMethods();返回一个Method[] 数组所有:getDeclaredMethods();返回一个Method[] 数组私有:getDeclaredMethod("方法名",参数1.....参数n),属性:
公开的指定:getField("方法名"),如String.class,要与方法中顺序一至,没有参数可以不写所有公开:getFields();返回一个Method[] 数组所有:getDeclaredFields();返回一个Method[] 数组私有:getDeclaredMethod("方法名",参数1.....参数n),
3.2、示例
packagecom.pb.demo1;//导入类importcom.pb.entity.Person;importjava.lang.reflect.*;/*获取公开构造方法
获取私有构造方法
获取公开的方法
获取私有的方法*/classReflectionDemo1 {publicstaticvoidmain(String[] args)throwsException {
getObj_con1();
System.out.println("=========================");
getObj_con2();
System.out.println("=========================");
getObj_con3();
System.out.println("=========================");
getObj_con4();
System.out.println("=========================");
getObj_meth1();
System.out.println("=========================");
getObj_meth2();
System.out.println("=========================");
getField_meth1();
System.out.println("=========================");
}/** 获取公开构造方法*/publicstaticvoidgetObj_con1()throwsException {
Class cla= Class.forName("com.pb.entity.Person");//获取无参数的构造方法Constructor<Person> con =cla.getConstructor();
System.out.println(con);//获取指定参数的构造方法有3个参数的构造方法Constructor<Person> cons = cla.getConstructor(String.class, String.class,int.class);
System.out.println(cons);
}/** 获取私有构造方法*/publicstaticvoidgetObj_con2()throwsException {
Class cla= Class.forName("com.pb.entity.Person");//获取私有一个参数的构造方法Constructor<Person> con1=cla.getDeclaredConstructor(String.class);
System.out.println(con1);//获取私有2个参数的构造方法Constructor<Person> con2=cla.getDeclaredConstructor(String.class,int.class);
System.out.println(con2);
}/** 获取全部公有构造方法*/publicstaticvoidgetObj_con3()throwsException {
Class cla= Class.forName("com.pb.entity.Person");
Constructor [] cons=cla.getConstructors();//遍历for(Constructor c:cons)
{
System.out.println(c);
}
}/** 获取全部构造方法包括私有*/publicstaticvoidgetObj_con4()throwsException {
Class cla= Class.forName("com.pb.entity.Person");
Constructor [] cons=cla.getDeclaredConstructors();//遍历for(Constructor c:cons)
{
System.out.println(c);
}
}/** 获取公开的方法*/publicstaticvoidgetObj_meth1()throwsException {
Class cla= Class.forName("com.pb.entity.Person");//获取方法名为show的公开方法Method m1=cla.getMethod("show");
System.out.println(m1);//获取setName的方法Method m2=cla.getMethod("setName", String.class);
System.out.println(m2);//获取所有公开的方法包括从Object中继承的方法Method [] ms=cla.getMethods();//遍历for(Method m:ms)
{
System.out.println(m);
}
}/** 获取私有的方法*/publicstaticvoidgetObj_meth2()throwsException {
Class cla= Class.forName("com.pb.entity.Person");//获取指定的私有方法名字为test,有2个字符串参数Method m1=cla.getDeclaredMethod("test", String.class,String.class);
System.out.println(m1);//也可以获取SET和get方法Method m2=cla.getDeclaredMethod("getAge");
System.out.println(m2);//获取全部方法包含私有Method [] ms=cla.getDeclaredMethods();//遍历for(Method m:ms)
{
System.out.println(m);
}
}/** 获取属性*/publicstaticvoidgetField_meth1()throwsException{
Class cla= Class.forName("com.pb.entity.Person");//获取指定的属性Field f1=cla.getDeclaredField("name");
System.out.println(f1);//有公开的话直接cla.getField(name)//获取所有属性Field [] fs=cla.getDeclaredFields();for(Field f:fs){
System.out.println(f);
}
}
}
结果
publiccom.pb.entity.Person()publiccom.pb.entity.Person(java.lang.String,java.lang.String,int)=========================privatecom.pb.entity.Person(java.lang.String)privatecom.pb.entity.Person(java.lang.String,int)=========================publiccom.pb.entity.Person(java.lang.String,java.lang.String,int)publiccom.pb.entity.Person()=========================publiccom.pb.entity.Person(java.lang.String,java.lang.String,int)publiccom.pb.entity.Person()privatecom.pb.entity.Person(java.lang.String)privatecom.pb.entity.Person(java.lang.String,int)=========================publicvoidcom.pb.entity.Person.show()publicvoidcom.pb.entity.Person.setName(java.lang.String)publicvoidcom.pb.entity.Person.show()publicvoidcom.pb.entity.Person.setGender(java.lang.String)publicjava.lang.String com.pb.entity.Person.getGender()publicstaticvoidcom.pb.entity.Person.staticMethod()publicjava.lang.String com.pb.entity.Person.getName()publicvoidcom.pb.entity.Person.setName(java.lang.String)publicfinalvoidjava.lang.Object.wait(long,int)throwsjava.lang.InterruptedExceptionpublicfinalnativevoidjava.lang.Object.wait(long)throwsjava.lang.InterruptedExceptionpublicfinalvoidjava.lang.Object.wait()throwsjava.lang.InterruptedExceptionpublicbooleanjava.lang.Object.equals(java.lang.Object)publicjava.lang.String java.lang.Object.toString()publicnativeintjava.lang.Object.hashCode()publicfinalnativejava.lang.Class java.lang.Object.getClass()publicfinalnativevoidjava.lang.Object.notify()publicfinalnativevoidjava.lang.Object.notifyAll()=========================privatevoidcom.pb.entity.Person.test(java.lang.String,java.lang.String)privateintcom.pb.entity.Person.getAge()publicvoidcom.pb.entity.Person.show()privateintcom.pb.entity.Person.getAge()publicvoidcom.pb.entity.Person.setGender(java.lang.String)publicjava.lang.String com.pb.entity.Person.getGender()publicstaticvoidcom.pb.entity.Person.staticMethod()privatevoidcom.pb.entity.Person.setAge(int)publicjava.lang.String com.pb.entity.Person.getName()publicvoidcom.pb.entity.Person.setName(java.lang.String)privatevoidcom.pb.entity.Person.test(java.lang.String,java.lang.String)privatevoidcom.pb.entity.Person.test()=========================privatejava.lang.String com.pb.entity.Person.nameprivatejava.lang.String com.pb.entity.Person.nameprivatejava.lang.String com.pb.entity.Person.genderprivateintcom.pb.entity.Person.age=========================
四、创建对象4.1、概述
两种创建对象的方式
使用指定构造方法创建对象使用newIntance()创建对象,这个方法要求类必须有默认的构造方法,空参数构造方法4.2、示例
packagecom.pb.demo1;//导入类importcom.pb.entity.Person;importjava.lang.reflect.*;publicclassReflectDemo2 {publicstaticvoidmain(String[] args)throwsException{
createObj1();
System.out.println("===============");
createObj2();
System.out.println("===============");
}/** 使用构造方法创建对象*/publicstaticvoidcreateObj1()throwsException {
Class cla= Class.forName("com.pb.entity.Person");//获取指定的构造方法 3 个参数的参数方法Constructor con=cla.getConstructor(String.class,String.class,int.class);
Person p=(Person) con.newInstance("张三","男",20);
p.show();
}/** 使用newInstance创建对象*/publicstaticvoidcreateObj2()throwsException {
Class cla= Class.forName("com.pb.entity.Person");
Person p=(Person) cla.newInstance();
p.show();
}
}
结果:
公开有参数构造方法
姓名:张三,性别:男,年龄:20
===============公开无参数构造方法
姓名:null,性别:null,年龄:0
===============
五、使用setter与getter5.1、概述
invoke(Object obj, Object... args)
对带有指定参数的指定对象调用由此Method对象表示的底层方法。setaccessible(boolean flag)
将此对象的accessible标志设置为指示的布尔值。true表示可以设置,默认为false
只针对私有private修饰的需要设置
5.2、示例
packagecom.pb.demo1;//导入类importcom.pb.entity.Person;importjava.lang.reflect.*;/***
* 使用反射,调用setter与getter方法
**/publicclassReflectDemo3 {publicstaticvoidmain(String[] args)throwsException {
setAndGet();
}publicstaticvoidsetAndGet()throwsException{
Class cla= Class.forName("com.pb.entity.Person");//创建对象Person p=(Person) cla.newInstance();//获取setter方法Method setName=cla.getMethod("setName", String.class);//赋值,第一个参数是对象,第二个参数是要设置的值setName.invoke(p, "张三");
Method setGender=cla.getMethod("setGender", String.class);//赋值,第一个参数是对象,第二个参数是要设置的值setGender.invoke(p, "女");
Method setAge=cla.getDeclaredMethod("setAge",int.class);//因为是私有的把权限打开才开以赋值setAge.setAccessible(true);//赋值,第一个参数是对象,第二个参数是要设置的值setAge.invoke(p, 32);//获取show方法Method show=cla.getMethod("show");//调用方法show.invoke(p);//多个参数,可以写NULL,也可以不写返回一个Objec类,这个方法因为已经输出}
}
六、动态创建数组
6.1、概述
java.lang.reflect.Array
6.2、示例
/*通过反射创建数组
创建一维数组或二维数组
1.通过Array.netInstance(类型.class,长度1,....长度n)
2.通过setXXX(数组名,下标,值)方法可以赋值
3.通过getXXX(数组名,下标)方法可以获取值*/importjava.lang.reflect.*;classReflectArray1
{publicstaticvoidmain(String[] args)
{
createArray1();
System.out.println("=====================");
createArray2();
}/*反射创建一个String类型长度为10的一维数组*/publicstaticvoidcreateArray1()
{
Object arr=Array.newInstance(String.class,10);//为其中一些下标元素赋值Array.set(arr,3,"hello");
Array.set(arr,5,"java");
Array.set(arr,7,"reflect");
Array.set(arr,8,"Array");
Array.set(arr,9,"!");//获取值Object o0=Array.get(arr,0);
Object o1=Array.get(arr,1);
Object o2=Array.get(arr,2);
Object o3=Array.get(arr,3);//下标为3的元素Object o4=Array.get(arr,4);
Object o5=Array.get(arr,5);
Object o6=Array.get(arr,6);
Object o7=Array.get(arr,7);
Object o8=Array.get(arr,8);
Object o9=Array.get(arr,9);//强制转换String [] str=(String[])arr;for(String s:str)
{
System.out.println(s);
}
}/*反射创建一个int类型长度为5,10的二维数组*/publicstaticvoidcreateArray2()
{
Object arr=Array.newInstance(int.class,5,10);//设置值//获取一数组的下标Object firstIndex1=Array.get(arr,3);//为二维数组下标一个元素设置值Array.setInt(firstIndex1,6,9);
Object firstIndex2=Array.get(arr,1);//为二维数组下标一个元素设置值Array.setInt(firstIndex2,2,2);//强转int[] [] arrs=(int[] [])arr;for(intx=0;x<arrs.length;x++)
{for(inty=0;y<arrs[x].length;y++){
System.out.print(arrs[x][y]+",");
}
System.out.println();
}
}
}