java 根据class获取对象_java基础—反射(根据Class获取对象信息Object.class)

Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。

//User类,子类

User user = new User();

//Parent类,User的父类

Parent parent = new Parent();

//获取类的类型Class的三种方式

Class z = User.class;

Class c = new User().getClass();

//动态获取

Class l = Class.forName("com.zqq.test.User");

字段操作 Field

Class c = user.getClass();

//获取当前字段类所有,不包含父类字段,返回Field数组

c.getDeclaredFields();

//获取当前类所有public修饰的字段,含父类public修饰的字段,返回Field数组

c.getFields();

//根据名称获取当前类字段 不包括父类,返回Field对象

c.getDeclaredField("age");

//根据字段名称获取public修饰的字段,包括父类字段,返回Field对象

c.getField("pubName");

//是否可以通过放射访问该字段 可以 true 不可以 false

Field.isAccessible();

//设置成可以通过反射访问该字段

Field.setAccessible(true);

Demo

User user = new User();

user.setName("xiaoxiao");

user.setAge(18);

User user1 = new User();

System.out.println(user == user1);

System.out.println(user.getClass() == user1.getClass());

Class c = user.getClass();

//getDeclaredFields 获取当前字段类所有,不包含父类字段

for(Field f : c.getDeclaredFields()){

System.out.println(f.getName());

}

// c.getFields() 获取当前类所有public修饰的字段,含父类public修饰的字段

for(Field f : c.getFields()){

System.out.println(f.getName());

}

// c.getDeclaredField 根据名称获取当前类字段 不包括父类

Field field = c.getDeclaredField("age");

System.out.println("字段信息====:" + field.toString());

//c.getField(name) 根据字段名称获取public修饰的字段,包括父类字段

//System.out.println("本身私有字段====age:" + c.getField("age")); // 报错 java.lang.NoSuchFieldException

System.out.println("本身public字段pubAge======pubAge:" + c.getField("pubAge"));

System.out.println("父类public修饰字段===========pubName :" + c.getField("pubName"));

//获取字段的值

Field nameField = c.getDeclaredField("name");

System.out.println("是否可以通过反射访问该字段:" + nameField.isAccessible());

// isAccessible为false时不可以通过反射访问该字段,设置成true

nameField.setAccessible(true);

System.out.println("是否可以通过反射访问该字段:" + nameField.isAccessible());

Object name = nameField.get(user);

System.out.println("获取到字段的值为:" + name);

//设置字段的值

nameField.set(user,"大小小");

System.out.println(user.getName());

方法操作 Method

Class c = User.class;

//获取public修饰的方法(包括父类),传入方法名称

c.getMethod("say");

//获取所有public修饰的方法(包括父类)

c.getMethods();

//获取当前类的方法(所有作用域)(不包括父类),传入方法名称

c.getDeclaredMethod("getName");

//获取当前类所有方法(不包括父类)

c.getDeclaredMethods();

//返回方法返回值类型

Method.getReturnType();

//返回方法参数类型

Method.getParameterTypes();

//返回方法的修饰符,public、private ...

Modifier.toString(Method.getModifiers());

//通过反射调用方法,传入对象的实例,静态方法实例传null

Method.invoke(new User(),'参数,没有不填');

//设置可以通过反射访问该方法

method.setAccessible(true);

Demo

Class c = User.class;

//获取public的方法(包括父类)

Method method = c.getMethod("say");

//获取所有public的方法包括父类

Method[] methods = c.getMethods();

//获取当前类的方法(所有作用域)(不包括父类)

method = c.getDeclaredMethod("getName");

//获取当前类所有方法(不包括父类)

methods = c.getDeclaredMethods();

System.out.println(method.toString());

System.out.println("方法名称:" + method.getName());

System.out.println("方法返回值类型:" + method.getReturnType());

System.out.println("方法的参数类型:" + method.getParameterTypes());

System.out.println("方法的修饰符:" + Modifier.toString(method.getModifiers()));

//调用方法

method = c.getMethod("say");

//传入对象的实例

method.invoke(new User());

//调用静态方法,实例传null

Method statciMethon = c.getMethod("sayStatic");

statciMethon.invoke(null);

//调用private修饰的方法,需要设置 Method.setAccessible(true),否则会报错 java.lang.NoSuchMethodException

method = c.getDeclaredMethod("sayPrivate");

method.setAccessible(true);

method.invoke(new User());

构造方法

//创建对象 , newInstance只能调用public修饰的无参构造方法,有参或者不是public修饰则创建不了对象

User user = User.class.newInstance();

user.setName("zqq");

System.out.println(user.toString());

//Java的反射API提供了Constructor对象,它包含一个构造方法的所有信息,可以创建一个实例,可以调用任意构造方法

Constructor constructor = User.class.getDeclaredConstructor(String.class);

User u = (User) constructor.newInstance("zqqqqq");

System.out.println(u.toString());

继承关系 ps:看框架源码的时候可以先获取对象的继承关系

Class c = User.class;

//获取父类的Class,返回对象,java单继承

c.getSuperclass();

//获取实现的接口,返回数组,java多实现

c.getInterfaces();

//isAssignableFrom() 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true

Parent.Class.isAssignableFrom(c);

Demo

//获取类类型的方式, 类类型 就是类的类型

Class z = User.class;

Class c = new User().getClass();

//传入类的完整类名

Class l = Class.forName("com.zqq.test.User");

//这三种方式获取的Class都是同一个Class,因为JVM对每个加载的Class只创建一个Class实例来表示它的类型

System.out.println(z == c && c == l);

//获取父类的Class ,阅读源码的时候可以无限往上看看都继承了哪个父类,继承的接口也一样

Class p = l.getSuperclass();

System.out.println("父类class:" + p);

//获取实现的接口

Class[] interfaces = l.getInterfaces();

for(Class inter : interfaces){

System.out.println(inter.toString());

}

// instanceof 判断某个实例是否是某个类型

System.out.println(new User() instanceof com.zqq.test.User);

// isAssignableFrom() 判定此 Class 对象所表示的类或接口与指定的 Class 参数所表示的类或接口是否相同,或是否是其超类或超接口。如果是则返回 true

System.out.println(User.class.isAssignableFrom(Parent.class));

System.out.println(Parent.class.isAssignableFrom(User.class));

【往期精彩视频】

你可能感兴趣的:(java,根据class获取对象)