概述
一:反射:框架设计的灵魂:
框架:半成品软件。可以在框架的基础上进行软件开发。简化编码。
反射:将类的各个组成部分封装为其他对象,这就是反射机制。
好处:
1:可以在程序运行过程中,操作这些对象。
2:可以解耦,提高程序的可扩展性。
获取Class对象的方式:
方式1: Class.forName("全类名");将字节码文件加载进内存。
(多用于配置文件,将类名定义在配置文件中。读取文件,加载类).
方式2:类名.class;通过类名的属性class获取。
(都用于参数的传递。
方式3:对象.getClass();getClass()方法在Object类中定义。
(多用于对象的获取字节码的方式)
结论:
同一个字节码(*.class)在一次程序运行过程中,只能被加载一次,不论通过哪一种方式获取的Class对象都是同一个。
Class对象功能:
获取功能:
1:获取成员变量们。
```cpp
Field[] getFields();//获取所有public修饰的成员变量。
Field getField(String name)//获取指定名称的public修饰的成员变量。
Field[] getDeclaredFields();//获取所有的成员变量,不考虑修饰符。
Field getDeclaredField(String name)获取指定名称的成员变量,不考虑修饰符。
2:获取构造方法们
Constructor<?>[] getConstructors();
Constructor<T> getConstructors(类<?>...parameterTypes)
Constructor<T> getDeclaredConStuctor(类<?>...parameterTypes)
3:获取成员方法们
Method[] getMethods();
Method[] getMethod(String name,类<?>....parameterTypes)
Method[] getDeclaredMethods();
Method[] getDeclaredMethod(String name,类<?> ...parameterTypes)
4:获取类名。
String getName();
Field:成员变量:
操作:
1:设置值。
void set(Object obj,Object value);
2:获取值。
get(Object obj);
3:忽略访问权限修饰符的安全检查。
setAccessible(true);//暴力反射;
二:反射_Class对象功能_获取Field
package domain;
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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{" +
"name='" + name + ''' +
", age=" + age +
", a='" + a + ''' +
", b='" + b + ''' +
", c='" + c + ''' +
", d='" + d + ''' +
'}';
}
public void eat(){
System.out.println("eat...");;
}
public void eat(String food){
System.out.println("eat..."+food);
}
}
package reflect;
import domain.Person;
import java.lang.reflect.Field;
/*
1:获取成员变量们。
Field[] getFields();
Field getField(String name)
Field[] getDeclaredFields();
Field getDeclaredField(String name)
```
2:获取构造方法们
Constructor<?>[] getConstructors();
Constructor<T> getConstructors(类<?>...parameterTypes)
Constructor<T> getDeclaredConStuctor(类<?>...parameterTypes)
3:获取成员方法们
Method[] getMethods();
Method[] getMethod(String name,类<?>....parameterTypes)
Method[] getDeclaredMethods();
Method[] getDeclaredMethod(String name,类<?> ...parameterTypes)
```
4:获取类名。
String getName();
*/
public class ReflectDemo2 {
public static void main(String[] args) throws Exception {
//获取Person的Class对象。
Class personClass = Person.class;
/*
1:获取成员变量们。
Field[] getFields();
Field getField(String name)
Field[] getDeclaredFields();
Field getDeclaredField(String name)
*/
// Field[] getFields();
Field[] fields =personClass.getFields();
for (Field field:fields){
System.out.println(field);
}
System.out.println("============================");
// Field getField(String name)
Field a =personClass.getField("a");
//获取成员变量a的值
Person p =new Person();
Object value =a.get(p);
System.out.println(value);
//设置a的值。
a.set(p,"张三" );
System.out.println(p);
System.out.println("========================");
//Field[] getDeclaredFields();//获取所有的成员变量,不考虑修饰符。
Field[] declaredFields =personClass.getDeclaredFields();
for (Field declaredField:declaredFields){
System.out.println(declaredField);
}
//Field getDeclaredField(String name)
Field d =personClass.getDeclaredField("d");
//忽略访问权限修饰符的安全检查。
d.setAccessible(true);//暴力反射;
Object value2 =d.get(p);
System.out.println(value2);
}
}
三:反射_Class对象功能_获取Constructor
Constructor:构造方法;
创建对象:
T newInStance(Object …initargs)
如果使用空参构造方法创建对象。操作可以简化的。
Object o =personClass.newInstance();
package reflect;
import domain.Person;
import java.lang.reflect.Constructor;
public class ReflectDemo3 {
public static void main(String[] args) throws Exception{
//获取Person的Class对象。
Class personClass = Person.class;
/*
2:获取构造方法们
Constructor<?>[] getConstructors();
Constructor<T> getConstructors(类<?>...parameterTypes)
Constructor<T> getDeclaredConStuctor(类<?>...parameterTypes)
Constructor<?>[] getDeclaredConstructors()
*/
// Constructor<T> getConstructors(类<?>...parameterTypes)
Constructor constructor = personClass.getConstructor(String.class,int.class);
System.out.println(constructor);
//创建对象:
Object person =constructor.newInstance("张三",23);
System.out.println(person);
System.out.println("==============");
Constructor constructor1 = personClass.getConstructor();
System.out.println(constructor);
//创建对象:
Object person1 =constructor1.newInstance();
System.out.println(person);
Object o =personClass.newInstance();
System.out.println(o);
//constructor1.setAccessible(true);
}
}
四:反射_Class对象功能_获取Method
Method:方法对象:
执行方法:
Object invoke(Object obj,Object...args)
获取方法名称:
String getName();//获取方法名称。
注:Person类代码如上。
package reflect;
import domain.Person;
import java.lang.reflect.Method;
/*
Method[] getMethods();
Method[] getMethod(String name,类<?>....parameterTypes)
Method[] getDeclaredMethods();
Method[] getDeclaredMethod(String name,类<?> ...parameterTypes)
*/
public class ReflectDemo4 {
public static void main(String[] args) throws Exception{
//获取Person的Class对象。
Class personClass = Person.class;
//获取指定名称的方法:
Method method=personClass.getMethod("eat");
Person p =new Person();
//执行方法
method.invoke(p);
Method method1=personClass.getMethod("eat",String.class);
//执行方法;
method1.invoke(p,"饭");
System.out.println("=================================");
//获取所有的public修饰的方法
Method[] methods =personClass.getMethods();
for (Method method3:methods){
System.out.println(method3);
// method3.setAccessible(true);//暴力反射
String name =method.getName();
System.out.println(name);
}
//获取类名;
String className =personClass.getName();
System.out.println(className);
}
}
五:反射_案例:
需求:写一个“框架",不能改变该类的任何代码的前提下,可以帮我们创建任意类的对象,并且执行其中任意方法。
1:配置文件
2:反射。
步骤;
1:将需要创建的对象的全类名和需要执行的方法定义在配置文件中。
2:在程序中加载配置文件。
3:使用反射技术来加载类文件进内存。
4:创建对象
5:执行方法。
代码结构:
Person类
package cn.itcast.domain;
public class Person {
private String name;
private int age;
public String a;
protected String b;
String c;
private String d;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
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{" +
"name='" + name + ''' +
", age=" + age +
", a='" + a + ''' +
", b='" + b + ''' +
", c='" + c + ''' +
", d='" + d + ''' +
'}';
}
public void eat(){
System.out.println("eat...");;
}
public void eat(String food){
System.out.println("eat..."+food);
}
}
pro.properties配置文件
className=cn.itcast.domain.Person
methodName=eat
reflect类
package cn.itcast.reflect;
import java.io.InputStream;
import java.lang.reflect.Method;
import java.util.Properties;
/*
框架类
*/
public class ReflectTest {
public static void main(String[] args) throws Exception{
//可以创建任意类的对象,可以去执行任意方法。
/*
* 前提:不能改变该类的任何代码,可以创建任意类的对象,可以去执行任意方法。
* */
//1.加载配置文件。
//1.1创建Properties对象
Properties pro =new Properties();
//1.2加载配置文件,转换为一个集合。
//1.2.1获取class目录下的配置文件。
ClassLoader classLoader=ReflectTest.class.getClassLoader();//获取类加载器。
InputStream is=classLoader.getResourceAsStream("cn/itcast/pro.properties");
pro.load(is);
//获取配置文件中定义的数据。
String className =pro.getProperty("className");
String methodName =pro.getProperty("methodName");
//3加载该类进内存。
Class cls =Class.forName(className);
//4:创建对象。
Object obj =cls.newInstance();
//5.获取方法对象
Method method =cls.getMethod(methodName);
//6.执行方法
method.invoke(obj);
}
}
结果;
最后
以上就是糟糕树叶为你收集整理的23:Java基础加强-反射的全部内容,希望文章能够帮你解决23:Java基础加强-反射所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复