java object类_Java 反射使用总结,看完这一篇就足够了

4872135d0faa969d8bb9892e0a11648b.png

反射机制是什么

反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

反射机制能做什么

反射机制主要提供了以下功能:

  • 在运行时判断任意一个对象所属的类;
  • 在运行时构造任意一个类的对象;
  • 在运行时判断任意一个类所具有的成员变量和方法;
  • 在运行时调用任意一个对象的方法;
  • 生成动态代理。

反射机制的相关API

定义一个接口 InterFace

package com.app;public interface InterFace { void read() ;}

定义一个 Person 类

package com.app;public class Person implements InterFace { private String id ; private String name ; public String age ; //构造函数1 public Person( ){ } //构造函数2 public Person( String id ){ this.id = id ; } //构造函数3 public Person( String id , String name ){ this.id = id ; this.name = name ; } public String getId() { return id; } public void setId(String id) { this.id = id; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } /** * 静态方法 */ public static void update(){ } @Override public void read() { }}
  • 获取类:3种方法
package com.app;public class T1 { public static void main(String[] args) { //第一种方法:forName try { Class> class1 = Class.forName("com.app.Person"); System.out.println( class1 ); } catch (ClassNotFoundException e) { e.printStackTrace(); } //第二张方法:class Class> class2 = Person.class;  //第三种方法:getClass Person person = new Person();  Class> class3 = person.getClass(); System.out.println( class2 ); System.out.println( class3 ); }}

运行结果:

class com.app.Personclass com.app.Personclass com.app.Person
  • 获取所有的方法:getMethods( )
package com.app;import java.lang.reflect.Method;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //获取所有的公共的方法 Method[] methods = class1.getMethods() ; for (Method method : methods) { System.out.println( method ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

//自定义方法public static void com.app.Person.update()public java.lang.String com.app.Person.getName()public void com.app.Person.read()public java.lang.String com.app.Person.getId()public void com.app.Person.setName(java.lang.String)public void com.app.Person.setId(java.lang.String)//父类Object类方法public final void java.lang.Object.wait() throws java.lang.InterruptedExceptionpublic final void java.lang.Object.wait(long,int) throws java.lang.InterruptedExceptionpublic final native void java.lang.Object.wait(long) throws java.lang.InterruptedExceptionpublic boolean java.lang.Object.equals(java.lang.Object)public java.lang.String java.lang.Object.toString()public native int java.lang.Object.hashCode()public final native java.lang.Class java.lang.Object.getClass()public final native void java.lang.Object.notify()public final native void java.lang.Object.notifyAll()
  • 获取所有实现的接口:getInterfaces()
package com.app;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //获取所有的接口 Class>[] interS = class1.getInterfaces() ; for (Class> class2 : interS ) { System.out.println( class2 ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

interface com.app.InterFace
  • 获取父类:getSuperclass()
package com.app;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //获取父类 Class> superclass = class1.getSuperclass() ; System.out.println( superclass ); } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

//父类是Object类class java.lang.Object
  • 获取所有的构造函数:getConstructors()
package com.app;import java.lang.reflect.Constructor;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //获取所有的构造函数 Constructor>[] constructors = class1.getConstructors() ; for (Constructor> constructor : constructors) { System.out.println( constructor ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

public com.app.Person(java.lang.String,java.lang.String)public com.app.Person(java.lang.String)public com.app.Person()
  • 获取所有的属性:getDeclaredFields();
package com.app;import java.lang.reflect.Constructor;import java.lang.reflect.Field;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //取得本类的全部属性 Field[] field = class1.getDeclaredFields(); for (Field field2 : field) { System.out.println( field2 ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

private java.lang.String com.app.Person.idprivate java.lang.String com.app.Person.name

可以看出属性的修饰符是: private , 数据类型:String ,名字:id/name

  • 创建实例:newInstance()
package com.app;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person");; //创建实例化:相当于 new 了一个对象 Object object = class1.newInstance() ; //向下转型 Person person = (Person) object ; } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}

getDeclaredFields 和 getFields 的区别

getDeclaredFields()获得某个类的所有申明的字段,即包括public、private和proteced,但是不包括父类的申明字段。getFields()获得某个类的所有的公共(public)的字段,包括父类。

小例子

package com.app;import java.lang.reflect.Field;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person");; //获得所有的字段属性:包括  Field[] declaredFields = class1.getDeclaredFields() ; Field[] fields = class1.getFields() ; for( Field field : declaredFields ){ System.out.println( "de-- " + field ); } for( Field field : fields ){ System.out.println( "fields-- " + field ); } } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

de-- private java.lang.String com.app.Person.idde-- private java.lang.String com.app.Person.namede-- public java.lang.String com.app.Person.agefields-- public java.lang.String com.app.Person.age

实战1:通过反射,获取对象实例,并且操作对象的方法

package com.app;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person");; //创建实例化:相当于 new 了一个对象 Object object = class1.newInstance() ; //向下转型  Person person = (Person) object ; person.setId( "100"); person.setName( "jack") ;  System.out.println( "id: " + person.getId() + " name: " + person.getName() ); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } }}

运行结果:

id: 100 name: jack

实战2:通过反射获取对象字段属性,并且赋值

package com.app;import java.lang.reflect.Field;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //给id 属性赋值 idField.set( person , "100") ; //打印 person 的属性值 System.out.println( idField.get( person )); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

java.lang.IllegalAccessException: Class com.app.T1 can not access a member of class com.app.Person with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(Unknown Source) at java.lang.reflect.AccessibleObject.checkAccess(Unknown Source) at java.lang.reflect.Field.set(Unknown Source) at com.app.T1.main(T1.java:20)

程序崩溃,原因是:id 这个属性的是 private 私有的,不能修改它的值。

改进:

添加 idField.setAccessible( true );

完整的代码为:

package com.app;import java.lang.reflect.Field;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  idField.setAccessible( true ); //给id 属性赋值 idField.set( person , "100") ; //打印 person 的属性值 System.out.println( idField.get( person )); } catch (InstantiationException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (NoSuchFieldException e) { e.printStackTrace(); } catch (SecurityException e) { e.printStackTrace() ; } catch (ClassNotFoundException e) { e.printStackTrace(); } }}

运行结果:

100

实战3:综合训练,反射操作属性和方法

package com.app;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;public class T1 { public static void main(String[] args) { try { //创建类 Class> class1 = Class.forName("com.app.Person"); //创建实例 Object person = class1.newInstance(); //获得id 属性 Field idField = class1.getDeclaredField( "id" ) ; //打破封装 实际上setAccessible是启用和禁用访问安全检查的开关,并不是为true就能访问为false就不能访问  //由于JDK的安全检查耗时较多.所以通过setAccessible(true)的方式关闭安全检查就可以达到提升反射速度的目的  idField.setAccessible( true ); //给id 属性赋值 idField.set( person , "100") ; //获取 setName() 方法 Method setName = class1.getDeclaredMethod( "setName
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值