新手学习java反射基础
一、反射
反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。对于反射的操作实际上就是通过Class对象获取:
*a、java.lang.reflect.Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。操作类的成员变量。
*b、java.lang.reflect.Constructor
*c、java.lang.reflect.Method:操作类的方法。
在学习反射基础前先创建一个Person对象作为实例
packagecom.jalja.org.base.relfect;
publicclassPerson{
privateStringname;
intage;
publicStringaddress;
publicPerson(){
}
privatePerson(Stringname){
this.name=name;
}
Person(Stringname,intage){
this.name=name;
this.age=age;
}
publicPerson(Stringname,intage,Stringaddress){
this.name=name;
this.age=age;
this.address=address;
}
publicvoidshow(){
System.out.println("show");
}
publicvoidmethod(Strings){
System.out.println("method"+s);
}
publicStringgetString(Strings,inti){
returns+"---"+i;
}
privatevoidfunction(){
System.out.println("function");
}
@Override
publicStringtoString(){
return"Person[name="+name+",age="+age+",address="+address
+"]";
}
}
二、获取类的Class对象
publicstaticvoidgetClassObject()throwsClassNotFoundException{
//方式一:Object的getClass()方法
Personperson1=newPerson();
Personperson2=newPerson();
Classc1=person1.getClass();
Classc2=person2.getClass();
System.out.println(person1==person2);//false
System.out.println(c1==c2);//true不管JVM内存中有多少个对象,对于字节码文件来说只有一份
//方式二:数据类型的静态class属性
Classc3=Person.class;
System.out.println(c1==c3);//true
//方式三:Class类的静态方法
//publicstaticClass>forName(StringclassName)throwsClassNotFoundException
Classc4=Class.forName("com.jalja.org.base.relfect.Person");
System.out.println(c1==c4);//true
}
三、java.lang.reflect.Constructor
1、获取Constructor对象
//获取Class对象所表示的类的构造方法
publicstaticvoidgetConstructorTest()throwsException{
Classc4=Class.forName("com.jalja.org.base.relfect.Person");
//1、获取Class对象所表示的类所有公共构造方法
//publicConstructor>[]getConstructors()throwsSecurityException
Constructor[]cs=c4.getConstructors();
//2、获取Class对象所表示的类所有构造方法
//publicConstructor>[]getDeclaredConstructors()throwsSecurityException
Constructor[]cs2=c4.getDeclaredConstructors();
//3、获取Class对象所表示类的指定指定公共构造方法,parameterTypes参数是Class对象的一个数组,是指定数据类型的字节码
//publicConstructorgetConstructor(Class>...parameterTypes);
Constructorcs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
//获取该构造函数publicPerson(Stringname,intage,Stringaddress)
Constructorcs4=c4.getConstructor(String.class,int.class,String.class);
//4、获取Clss对象所表示类指定的构造范法官parameterTypes参数是Class对象的一个数组,它按声明顺序标识构造方法的形参类型的字节码。
//publicConstructorgetDeclaredConstructor(Class>...parameterTypes);
//获取该构造函数privatePerson(Stringname)的Constructor对象
Constructorcs5=c4.getDeclaredConstructor(String.class);
}
2、通过Constructor对象创建Class对象所表示类的实例
publicstaticvoidcreateObject()throwsException{
Classc4=Class.forName("com.jalja.org.base.relfect.Person");
//使用此Constructor对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
//publicTnewInstance(Object...initargs);
//Personperson=newPerson()
Constructorcs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
Objectobj=cs3.newInstance();
//Personperson=newPerson("jalja",21,"北京");
Constructorcs4=c4.getConstructor(String.class,int.class,String.class);
Objectobj1=cs4.newInstance("jalja",21,"北京");
System.out.println(obj1);//Person[name=jalja,age=21,address=北京]
//实例化一个私有的构造函数privatePerson(Stringname)
//控制java的访问检查
//publicvoidsetAccessible(booleanflag)
//将此对象的accessible标志设置为指示的布尔值。值为true则指示反射的对象在使用时应该取消Java语言访问检查。
//值为false则指示反射的对象应该实施Java语言访问检查。
Constructorcs5=c4.getDeclaredConstructor(String.class);
cs5.setAccessible(true);
Objectobj2=cs5.newInstance("张三丰");
System.out.println(obj2);//Person[name=张三丰,age=0,address=null]
}
四、java.lang.reflect.Field
1、获取Field对象
//获取Class类的Field对象
publicstaticvoidgetFieldTest()throwsException{
Classcs=Class.forName("com.jalja.org.base.relfect.Person");
//1、publicField[]getFields()throwsSecurityException
//获取Class对象所表示的类或接口的所有可访问公共(public修饰的)字段
Field[]fs=cs.getFields();
//2、publicField[]getDeclaredFields()throwsSecurityException
//获取Class对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
Field[]fs1=cs.getDeclaredFields();
//3、publicFieldgetField(Stringname)throwsNoSuchFieldException,SecurityException;
//获取Class对象所表示的类或接口的指定公共成员(public修饰)字段。name参数是一个String,用于指定所需字段的简称
Fieldfs2=cs.getField("address");
//publicFieldgetDeclaredField(Stringname)throwsNoSuchFieldException,SecurityException
//获取Class对象所表示的类或接口的指定已声明字段。name参数是一个String,它指定所需字段的简称
Fieldfs3=cs.getDeclaredField("name");
System.out.println(fs3);
}
2、通过Field对象对指定类属性赋值
//使用Field对象
publicstaticvoidcreateVarValue()throwsException{
Classcs=Class.forName("com.jalja.org.base.relfect.Person");
Objectobj=cs.getConstructor().newInstance();
FieldaddressField=cs.getField("address");
//publicvoidset(Objectobj,Objectvalue);
//将指定对象变量上此Field对象表示的字段设置为指定的新值。如果底层字段的类型为基本类型,则对新值进行自动解包
//obj-应该修改其字段的对象value-正被修改的obj的字段的新值
addressField.set(obj,"北京");
System.out.println(obj);//Person[name=null,age=0,address=北京]
//对非public修饰的变量操作
FieldnameField=cs.getDeclaredField("name");
//控制java的访问检查
nameField.setAccessible(true);
nameField.set(obj,"张三丰");
System.out.println(obj);//Person[name=张三丰,age=0,address=北京]
}
五、java.lang.reflect.Method
1、获取Method对象
//获取Method对象
publicstaticvoidgetMethodTest()throwsException{
Classcs=Class.forName("com.jalja.org.base.relfect.Person");
//1、publicMethod[]getMethods()throwsSecurityException
//获取Class对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共member方法。
Method[]m1=cs.getMethods();
//2、publicMethod[]getDeclaredMethods()throwsSecurityException
//获取Class对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
Method[]m2=cs.getDeclaredMethods();
//3、publicMethodgetMethod(Stringname,Class>...parameterTypes)throwsNoSuchMethodException,SecurityException;
//获取Class对象所表示的类或接口的指定公共成员方法。name参数是一个String,用于指定所需方法的简称。parameterTypes参数是按声明顺序标识该方法形参类型的Class对象的一个数组
Methodm3=cs.getMethod("show");//无参的方法
Methodm4=cs.getMethod("method",String.class);//带参的方法
//publicMethodgetDeclaredMethod(Stringname,Class>...parameterTypes)throwsNoSuchMethodException,SecurityException
//Class对象所表示的类或接口的指定已声明方法。name参数是一个String,它指定所需方法的简称,parameterTypes参数是Class对象的一个数组
Methodm5=cs.getDeclaredMethod("function");//无参的方法
System.out.println(m5);
}
2、通过Method对象调用指定类的方法
//Method对象的使用
publicstaticvoidcreateMethod()throwsException{
Classcs=Class.forName("com.jalja.org.base.relfect.Person");
Objectobj=cs.getConstructor().newInstance();
Methodm3=cs.getMethod("show");//无参的方法
//publicObjectinvoke(Objectobj,Object...args)
//对带有指定参数的指定对象调用由此Method对象表示的底层方法obj-从中调用底层方法的对象args-用于方法调用的参数
m3.invoke(obj);
//对带参方法的操作
Methodm4=cs.getMethod("method",String.class);//带参的方法
m4.invoke(obj,"北京");
//对有返回值得方法操作
Methodm6=cs.getMethod("getString",String.class,int.class);//带参的方法
Objectstr=m6.invoke(obj,"北京",200);
System.out.println(str);
//对私有无参方法的操作
Methodm5=cs.getDeclaredMethod("function");
m5.setAccessible(true);
m5.invoke(obj);
}
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。