java 打印对象属性 工具类_java 反射(reflect)总结,附对象打印工具类

要记住一切都是由Class对象开始,java.lang.Class是反射入口。

获取类的基本信息

我们可以通过一个类的Class对象了解该类的基本信息。

Javaclass内部模块

Javaclass内部模块说明

相应之ReflectionAPI,多半为Classmethods。

返回值类型(returntype)

package

class隶属哪个package

getPackage()

Package

field

class的属性

按访问权限分为:

所有、可访问

getDeclaredFields();

getDeclaredField(String name);

Field[]

Field

method

class的方法

按访问权限分为:

所有、可访问

getMethods();

getMethod(String name, Class>...parameterTypes);

Method[]

Method

modifier

class(或methods,fields)的属性

intgetModifiers()

Modifier.toString(int)

Modifier.isInterface(int)

int

String

bool

classnameorinterfacename

class/interface

名称getName()

String

typeparameters

参数化类型的名称

getTypeParameters()

TypeVariable

[]

baseclass

baseclass(只可能一个)

getSuperClass()

Class或null

implementedinterfaces

实现有哪些interfaces

getInterfaces()

Class[]

innerclasses

内部classes

getDeclaredClasses()

Class[]

outerclass

如果我们观察的class本身是innerclasses,那么相对它就会有个outerclass。

getDeclaringClass()

Class

下面我们来实践一下:

Person.java

class Person {

private int age;

private String name;

public Person() {

super();

}

public Person(int age, String name) {

this.age = age;

this.name = name;

}

public void say(){

System.out.println("Person say!");

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

@Override

public String toString() {

return "Person [age=" + age + ", name=" + name + "]";

}

}

测试:注:MyTestUtil是我用反射写的用于打印对象的属性值工具类。

public static void main(String[] args) {

Class demo1 = null;

try {

demo1 = Class.forName("study.javacore.test.Person");

} catch (ClassNotFoundException e1) {

e1.printStackTrace();

}

Class demo = Person.class;

System.out.println(demo1 == demo);// true

System.out.println(demo.getPackage());// 包名

System.out.println(demo.getModifiers());// 访问权限修饰符,0就是没有

MyTestUtil.print(demo.getConstructors());// 构成方法

MyTestUtil.print(demo.getDeclaredFields());// 字段信息

MyTestUtil.print(demo.getMethods());// 方法信息

}

获取类的实例

获取累的实例有两种方法:

通过Class对象的newInstance方法,创建此 Class 对象所表示的类的一个新实例。

try {

// 调用的是无参的构成方法,如果没有无参数的构造方法报错。

Person person =(Person) demo.newInstance();

person.setAge(10);

person.setName("klguang");

MyTestUtil.printWithSign("person", person);

} catch (Exception e) {

System.out.println("Class newInstance wrong!!!");

e.printStackTrace();

}

通过Constructor对象,获取类的实例。

try {

Class[] types = new Class[] { int.class, String.class };

Constructor constructor = demo.getConstructor(types);

Person person2 = constructor.newInstance(20, "klguang");

MyTestUtil.printWithSign("person2", person2);

} catch (Exception e) {

System.out.println("::constructor wrong!!!");

e.printStackTrace();

}

操作实例的属性

可通过Class对象的getDeclaredFields() 或getDeclaredField(String name) 方法取得字段Field对象,然后调用field.setAccessible(true),允许访问字段,最后用field.set(Object obj,Object value)或field.get(Object obj)来设置和获取字段的值。

Person person3=new Person(20,"klguang");

Field[] fileds = demo.getDeclaredFields();

for (Field field : fileds) {

field.setAccessible(true);// 设置些属性是可以访问的

String name=field.getName();//取得field的名称

try {

Object value = field.get(person3);// 得到此属性的值

System.out.println("fieldName:"+name+"\tfieldValue:"+value);

if(name.equals("age"))

field.set(person3, 40);

} catch (Exception e) {

e.printStackTrace();

}

}

MyTestUtil.printWithSign("person after access filed", person3);

调用实例的方法

可通过Class对象的getMethods() 或getMethod(String name, Class>...parameterTypes)方法取得Method对象,通过method.invoke(Object obj, Object... args)调用obj对象的方法。

Person person4=new Person(20,"klguang");

Method methods[] = demo.getMethods();

for (java.lang.reflect.Method method : methods) {

if (method.getName().startsWith("get")) {

try {

Object value=method.invoke(person4, null);

System.out.println("method invoke , return value is "+value);

} catch (Exception e) {

System.err.println("method invoke wrong!!");

}

}

}

反射实践,控制台打印工具类

我用反射写了一个打印对象的属性值工具类MyTestUtil,在控制台格式化输出对象属性。因此,可以不用在以后测试javabean时候,复写toString();当然复写了更好。

该工具类用到的反射方法如下:

/**

*

*

* @param object

* @param recursion

* 是否要递归

* @return

*/

private static String beanToStr(Object object, boolean recursion) {

if (object == null)

return "null";

Class clazz = object.getClass();

StringBuilder sb = new StringBuilder();

//返回源代码中给出的底层类的简称

sb.append(clazz.getSimpleName()).append("[");

Field[] fields = sortFieldByType(clazz.getDeclaredFields());

int iMax = fields.length - 1;

if (iMax == -1)

return sb.append("]").toString();

for (int i = 0;; i++) {

Field field = fields[i];

field.setAccessible(true);// 设置些属性是可以访问的

String name = field.getName();// 取得field的名称

if (name.equals("serialVersionUID"))

continue;

try {

Object value = field.get(object);// 得到此属性的值

if (isSimpleType(value) || !recursion)

sb.append(name + " = " + String.valueOf(value));

else

sb.append("\r\n" + indent(clazz.getSimpleName().length() + 2," ")

+ objToStr(value, false) + "\r\n");

} catch (Exception e) {

e.printStackTrace();

}

if (i == iMax)

return sb.append("]").toString();

sb.append(",");

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值