二刷java基础第二十二天——反射
Posted 名字真的很急用
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了二刷java基础第二十二天——反射相关的知识,希望对你有一定的参考价值。
一:什么是反射?
- 利用代码区中的数据(class),去创建对象;而不需要去new
- 构造方法
- 成员变量
- 成员方法
- 在代码区存储的class并不是真正的class文件(物理),而是一个虚拟的对象(Class)
二:Class
-
管理class文件对象
-
获取class文件对象的三种方式
-
方式一:通过Object类中的getClass()方法 方式二:类名.class获取到字节码文件对象(任意的数据类型,都默认具有静态的class属性) 方式三:forName("全路径")
public class 反射 {
public static void main(String[] args) throws ClassNotFoundException {
// TODO Auto-generated method stub
//代码区中的都是运行时状态
//获取class文件对象的三种方式
// 方式一:通过Object类中的getClass()方法
//方式二:类名.class获取到字节码文件对象(任意的数据类型,都默认具有静态的class属性)
//方式三:forName("全路径")
Person p = new Person();
Class a= p.getClass();
System.out.println(a);
Class b =Person.class;
System.out.println(b);
Class c =Class.forName("BJday29.Person"); //要写全路径
System.out.println(c);
//Class内部结构
//构造方法
//成员方法
//成员变量
}
}
class Person{
}
三:class文件的内部成员
- 构造方法:Constructor
- 成员方法: Method
- 成员变量: Filed
四:获取构造方法
Constructor<T> getConstructor(类<?>... parameterTypes)
返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。
Constructor<?>[] getConstructors()
返回包含一个数组 Constructor对象反射由此表示的类的所有公共构造 类对象。
====================================================================
Constructor<T> getDeclaredConstructor(类<?>... parameterTypes)
返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
Constructor<?>[] getDeclaredConstructors()
返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。
-
利用构造方法创建实例,类似new对象。
-
newInstance(Object... initargs) //可变参,参数可以为0,1个或2个,几个....
-
package BJday29;
import java.lang.reflect.Constructor;
public class 反射的成员 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Class<?> c =Class.forName("BJday29.Student");
//利用该对象获取公共的所有的构造方法
Constructor<?>[] constructors = c.getConstructors();
//返回一个反映 Constructor对象表示的类声明的所有 Constructor对象的数组 类 。
//Constructor<?>[] declaredConstructor = c.getDeclaredConstructors();
// for(Constructor s:constructors) {
// System.out.println(s);
// }
//获取指定的构造方法
//getConstructor(类<?>... parameterTypes)
//返回一个 Constructor对象,该对象反映 Constructor对象表示的类的指定的公共 类函数。
//Constructor<?> constructor = c.getConstructor(String.class,int.class);
//getDeclaredConstructor(类<?>... parameterTypes)
//返回一个 Constructor对象,该对象反映 Constructor对象表示的类或接口的指定 类函数。
// Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class);
//newInstance()
//创建由此 类对象表示的类的新实例。
//Constructor<?> constructor = c.getConstructor(int.class); //获得公共的无参构造方法
//Student s = (Student)constructor.newInstance(1);
// System.out.println(s);
//能否获得私有的构造方法并创建对象
//Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class);
//Student s = (Student)declaredConstructor.newInstance("tom");
//System.out.println(s); //会报错 因为安全检查机制 ,所有要想实现 ,我们需要解除这个安全机制,
Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//我们需要解除这个安全机制,暴力破解
Student s = (Student)declaredConstructor.newInstance("tom");
System.out.println(s);
}
}
class Student {
public int age;
public String sex;
Object obj = new Object();
protected double sum;
private int a;
private String name;
public Student() {
System.out.println("公开空参");
}
// public Student(int a) {
// this.a=a;
// System.out.println("公开的有参");
// }
private Student(String name) {
this.name=name;
System.out.println("私有空参");
}
public Student(String name,int a) {
System.out.println("私有的有参");
}
@Override
public String toString() {
return "Student [a=" + a + ", name=" + name + "]";
}
//成员方法
public String getName() {
return name;
}
public void setName(String name) {
this.name=name;
}
private int getA() {
return a;
}
private void setA(int a) {
this.a = a;
}
}
五:获取成员变量
-
Field getDeclaredField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。 Field[] getDeclaredFields() 返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象 ============================================================= Field getField(String name) 返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。 Field[] getFields() 返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
-
利用反射,给成员变量赋值
set(Object obj, Object value):
- obj:要将该字段绑定在某个对象上
- 给字段赋值
package BJday29;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
public class 反射的成员变量 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Class<?> c =Class.forName("BJday29.Student");
//Field getField(String name)
//返回一个 Field对象,它反映此表示的类或接口的指定公共成员字段 类对象。
//Field[] getFields()
//返回包含一个数组 Field对象反射由此表示的类或接口的所有可访问的公共字段 类对象。
//Field getDeclaredField(String name)
//返回一个 Field对象,它反映此表示的类或接口的指定已声明字段 类对象。
//Field[] getDeclaredFields()
//返回的数组 Field对象反映此表示的类或接口声明的所有字段 类对象。
// Field[] fields = c.getFields(); //获取所有公共的变量
// for(Field f:fields) {
// System.out.println(f);
// }
//获取所有的变量
// Field[] fields2 = c.getDeclaredFields();
// for(Field f:fields2) {
// System.out.println(f);
// }
//获取指定的变量
Field field3 = c.getDeclaredField("obj");
//System.out.println(field3);
Field field4 = c.getDeclaredField("age");
//System.out.println(field4);
//获取构造方法 为对象设置属性值
Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//我们需要解除这个安全机制,暴力破解
Student s = (Student)declaredConstructor.newInstance("tom");
//获取指定的公开成员变量
Field sex =c.getDeclaredField("name");
sex.setAccessible(true);
//set(Object obj, Object value)
//将指定对象参数上的此 Field对象表示的字段设置为指定的新值。
sex.set(s, "man"); //会把构造函数的赋值给覆盖
System.out.println(s);
}
}
六:成员方法
方法 getMethod(String name, 类<?>... parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
方法[] getMethods()
返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。
============================================================
getDeclaredMethod(String name, 类<?>... parameterTypes)
返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
方法[] getDeclaredMethods()
返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
package BJday29;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class 反射成员方法 {
public static void main(String[] args) throws Exception {
// TODO Auto-generated method stub
Class<?> c =Class.forName("BJday29.Student");
//方法 getDeclaredMethod(String name, 类<?>... parameterTypes)
//返回一个 方法对象,它反映此表示的类或接口的指定声明的方法 类对象。
//方法[] getDeclaredMethods()
//返回包含一个数组 方法对象反射的类或接口的所有声明的方法,通过此表示 类对象,包括公共,保护,默认(包)访问和私有方法,但不包括继承的方法。
//方法 getMethod(String name, 类<?>... parameterTypes)
//返回一个 方法对象,它反映此表示的类或接口的指定公共成员方法 类对象。
//方法[] getMethods()
//返回包含一个数组 方法对象反射由此表示的类或接口的所有公共方法 类对象,包括那些由类或接口和那些从超类和超接口继承的声明。
//invoke(Object obj, Object... args)
//在具有指定参数的 方法对象上调用此 方法对象表示的底层方法。
Constructor<?> declaredConstructor = c.getDeclaredConstructor(String.class);
declaredConstructor.setAccessible(true);//我们需要解除这个安全机制,暴力破解
Student s = (Student)declaredConstructor.newInstance("jack");
//Method[] methods = c.getMethods();
//Method method = c.getMethod("setName", String.class);
//Method[] methods2 = c.getDeclaredMethods();
Method method2 = c.getDeclaredMethod("setA", int.class);
method2.setAccessible(true);
Field sex =c.getDeclaredField("name");
sex.setAccessible(true);
sex.set(s, "man");
method2.invoke(s, 100);
System.out.println(s);
}
}
七:练习题
-
泛型擦除
-
package 泛型擦除; import java.lang.reflect.Method; import java.util.ArrayList; public class Demo { public static void main(String[] args) throws Exception{ ArrayList<Integer> list = new ArrayList(); list.add(1); list.add(200); // list.add("abc"); Class<?> aClass = Class.forName("java.util.ArrayList"); Method add = aClass.getMethod("add", Object.class); //暴力破解 add.setAccessible(true); //将该方法和对象进行绑定 add.invoke(list,"哈哈"); System.out.println(list); } }
-
以上是关于二刷java基础第二十二天——反射的主要内容,如果未能解决你的问题,请参考以下文章