JAVA程序进阶——反射
JAVA反射机制:将类的各个组成部分封装为其他对象。
可以将类的构造方法,成员方法,成员变量 封装成单独的类
好处: 1. 在程序运行过程中,操作这些对象。
2. 可以解耦,提高程序的扩展性
1.获得Class类的实例
阶段一:
已知一个类的全类名,且该类在类路径下,可以通过Class类的静态方法
forName()获取,但是要抛出异常
Class clazz=Class.forName("路径");
//多用于配置文件,将类名定义在配置文件中,读取文件加载类
阶段二:
已知具体的类,通过类的class属性获取,该方法最为安全可靠,程序性能最高。
Class clazz=类名.class;
//多用于参数的传递
阶段三:
已知某个类的实例,调用该实例的getClass()方法获取Class对象
Class clazz=对象名.getClass();
- 注意: 一个类只有Class
2. Class对象功能——获取功能
1 .获得成员变量们
-
-
Field
getField(String name)
返回一个Field
对象反映的类或接口的类
对象表示的指定公共成员。Field[]
getFields()
返回一个数组包含Field
物体反射的类或接口的类
对象代表所有可访问的公共领域。
-
Class personClass = Person.class;
Field name = personClass.getField("name");
System.out.println(name);
该方法可以获取任何修饰下的成员变量包括private
-
-
Field
getDeclaredField(String name)
返回一个对象,反映了Field
指定声明字段的类或接口的类
对象表示。Field[]
getDeclaredFields()
返回Field
物体反射所有字段的类或接口的类
对象表示声明数组。
-
Field age = personClass.getDeclaredField("age");
System.out.println(age);
- 操作成员变量
-
设置成员变量 set( )
-
-
void
set(Object obj, Object value)
设置域为代表的这 Field
对象指定对象上的参数指定的新价值。
-
Field name = personClass.getField("name");
name.set(person,"zhang");
System.out.println(person);
-
获得成员变量get( )
-
-
Object
get(Object obj)
返回的 Field
表示字段的值,指定对象上。
-
Object o = age.get(person);
age.setAccessible(true);//允许暴力反射,否则会提示安全问题
System.out.println(o);
2.获取构造方法们
-
-
Constructor<T>
getConstructor(类<?>... parameterTypes)
返回一个Constructor
对象反映指定的公共构造函数的类
对象表示的类。Constructor<?>[]
getConstructors()
返回一个数组包含Constructor
物体反射所有的类
对象表示的类的公共构造函数。
-
Constructor constructor = personClass.getConstructor(String.class, int.class);
System.out.println(constructor);
Class 这个自带了创建了无参构造方法
T | newInstance() |
---|---|
创建这个 类 对象表示的类的一个新实例。 |
Object o1 = personClass.newInstance();
o1.toString();
-操作构造器
-
创建有参对象
-
-
T
newInstance(Object... initargs)
利用这 Constructor
对象创建和初始化的构造函数的声明类的一个新实例构造函数,用指定的初始化参数。
-
Object zhang = constructor.newInstance("zhang", 18);
System.out.println(zhang);
3.获取成员方法们
-
-
方法
getMethod(String name, 类<?>... parameterTypes)
返回一个方法
对象反映的类或接口的类
对象表示的指定公共成员方法。方法[]
getMethods()
返回一个数组包含方法
物体反射所有的类或接口的类
对象表示的公共方法,包括那些由类或接口的超类和超接口继承的声明。
-
Method show = personClass.getMethod("show",int.class);
System.out.println(show);
//遍历成员方法不仅会遍历出当前类的公共成员方法还会遍历出 父类的成员方法
Method[] methods = personClass.getMethods();
for (Method method:methods)
{
System.out.println(method);
}
-
-
方法
getDeclaredMethod(String name, 类<?>... parameterTypes)
返回一个方法
对象反映指定声明方法的类或接口的类
对象表示。方法[]
getDeclaredMethods()
返回一个数组包含方法
物体反射所有声明的方法的类或接口的类
对象,代表包括公众、保护,默认(包)的访问,和私有方法,但不包括继承的方法
-
//同样的 私有成员方法也可通过反射获得 需要允许暴力反射否则会包安全错误
Method password = personClass.getDeclaredMethod("password");
password.setAccessible(true);//允许暴力反射
password.invoke(person);
-操作成员方法
-
-
Object
invoke(Object obj, Object... args)
调用底层的方法,这 方法
对象表示,对指定对象的指定参数。
-
//有参成员方法
Method show = personClass.getMethod("show",int.class);
show.invoke(person,10);
//无参成员方法
Method method = personClass.getMethod("toString");
method.invoke(person);
-
-
String
getName()
返回的 方法
对象表示的方法的名称,作为一个String
。
-
Method[] methods = personClass.getMethods();
for (Method method:methods)
{
System.out.println(method.getName());
}//返回该成员的方法名称,包括父类的
4.获取类名
-
-
String
getName()
返回单位名称(类,接口,数组类,原始类型,或无效)的 类
对象表示,作为一个String
。
-
5.获取包名
-
-
软件包
getPackage()
获取此类的包。
-
3. 通过配置文件反射获得
1.首先需要在src下创建 一个properties配置文件
2.创建一个 配置文件对象
Properties properties = new Properties();
3.用反射机制得到 Class
Class personClass1 = Person.class;
4.通过Class得到类加载器
类加载器的作用就是把类加载到内存中
ClassLoader classLoader = personClass1.getClassLoader();
5. 加载配置文件
-
-
InputStream
getResourceAsStream(String name)
返回用于读取指定资源的输入流。 InputStream resourceAsStream = classLoader.getResourceAsStream("db.properties");
-
6. 在输入流加载到资源中
-
-
void
load(InputStream inStream)
从输入字节流中读取属性列表(键和元素对)。
-
properties.load(inputStream);
6.获得配置文件的数据
-
-
String
getProperty(String key)
在这个属性列表中搜索指定的键的属性。
-
driver = properties.getProperty("driver");