从零开始学Java-08 反射

反射

反射:在程序运行的过程中,通过Class对象动态地获取到类的构造方法,成员方法,成员变量,并且操作构造方法,成员变量,成员方法

Class类

class 类的实例表示正在运行的Java应用程序中的类和接口,class对象是加载类时由JVM以及通过调用类加载器中的defineclass方法自动构造的。—JVM创建好了,不需要我们创建

得到Class对象的方式

     Class cls1= String.class;// --类名.class
     Class<?>  cls2 = "12356".getClass();//--对象.getClass()
     Class<?> cls3 = Class.forName("java.lang.String");//--包名.类名
URL getResource(String name)//--类路径.返回的是 ***.class字节码文件所在的位置: 实体类.class.getResource(文件名).getpath();//可以拿到文件所在位置//bin目录
		Student stu1 = new Student();//这一new 产生一个Student对象,一个Class对象。
		Class stuClass = stu1.getClass();//获取Class对象
		System.out.println(stuClass.getName());
		
		//第二种方式获取Class对象
		Class stuClass2 = Student.class;
		System.out.println(stuClass == stuClass2);//判断第一种方式获取的Class对象和第二种方式获取的是否是同一个
		
		//第三种方式获取Class对象
		try {
			Class stuClass3 = Class.forName("包名.Student");//注意此字符串必须是真实路径,就是带包名的类路径,包名.类名
			System.out.println(stuClass3 == stuClass2);//判断三种方式是否获取的是同一个Class对象
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}


Constructor类

–描述类中的构造方法,通过Constructor可以拿来创建对象

--
得到一个public构造方法        ---c1=cls1.getConstructor()
通过构造方法对象创建对象    ---s1 = c1.newInstance();等价于空参构造
--  
 根据参数类型去匹配构造方法     --c2=cls2.getConstructor(String.class,int.class)                                                                   --s2 = c2.newInstance("string", int);等价于满参构造
--
得到一个声明的构造方法            --c3=cls3.getDeclareConstructor(String.class)
对于私有内容需要暴力反射         --c3.setAccessible(true)
                                                  --c3.newInstance("string")
--
得到所有public的构造方法   
Constructor[] cons = cls.getConstructors();
for (Constructor c : cons) { System.out.println(c);}
--
得到所有声明的构造方法
Constructor[] cons2 = cls.getDeclaredConstructors();
for (Constructor c : cons2) {System.out.println(c);}

Method

描述类中的普通方法,普通方法可以调用

// 1.拿到Class对象
Class<?> cls = Employee.class;
Employee obj = cls.newInstance(); // 使用的是无参构造    
// 2.1.得到一个public方法
// name: 方法名
// parameterTypes: 方法的参数
Method m1 = cls.getMethod("getUp"); // 找到方法
/*Object invoke(Object obj, Object... args)
来执行这个方法,
Object obj:执行对象的方法
Object... args:方法的参数*/
m1.invoke(obj); // 执行方法 等价于 obj.getUp();
// 2.得到一个声明的方法
Method m2 = cls.getDeclaredMethod("eat", String.class);
m2.setAccessible(true);
Object re = m2.invoke(obj, "面包..."); // 等价于 String re = obj.eat("面包");
System.out.println("返回值: " + re); // invoke方法的返回值就是实际方法的返回值    
// 静态方法的调用,直接传入null作为调用对象
Method m3 = cls.getMethod("sleep");
m3.invoke(null);
// 3.得到所有public的方法(包含父类的)
Method[] methods = cls.getMethods();
for (Method m : methods) {
System.out.println(m);}
// 4.得到本类所有声明的方法
Method[] declaredMethods = cls.getDeclaredMethods();
for (Method m : declaredMethods) {
System.out.println(m);}
Field类

描述类中的成员变量,可以设置和取出成员变量中的值

得到Field对象
通过Class的方法
1.得到一个public成员变量
public Field getField(String name)   
2.得到一个声明的成员变量
public Field getDeclaredField(String name)  
3.得到所有public的成员变量
public Field[] getFields()
4.得到所有声明的成员变量
public Field[] getDeclaredFields()
1.获取成员变量的名称: getName()
2.获取成员变量的类型: getType()
3.给成员变量赋值
3.1. 给基本类型赋值
void setXxx(Object obj, xxx x)
Object obj: 要设置属性的对象
xxx x: 成员变量的值
3.2. 给引用类型赋值
void set(Object obj, Object value)
Object obj: 要设置属性的对象
Object value: 成员变量的值    
4.得到成员变量的值
3.1 得到基本数据类型成员变量的值
xxx getXxx(Object obj)
Object obj: 获取成员变量的对象
xxx: 返回值       
3.2 得到引用数据类型成员变量的值
Object get(Object obj)
Object obj: 获取成员变量的对象
Object: 返回值

Properties类

–表示一个持久的属性集,可保存在流中或从流中加载.属性列表中的每一个键及其对应的值都是一个字符串
特点:键值类型:是字符串
使用:Properties()-创建一个空的Properties集合

使用步骤:

1.定义Properties文件
#Person\u7684\u4FE1\u606F
 className=com.leiyuee.demo08.Person
 name=\u674E\u56DB
 gender=\u7537
 age=20
 #Dog\u7684\u4FE1\u606F
 #className=com.leiyuee.demo08.Dog
 #name=\u65FA\u8D22
 #color=\u68D5\u8272
 #age=3


2.定义类
                                    
3.将info.properties文件中的数据加载到程序中
将info.properties文件中的数据加载到程序中
Properties pp = new Properties();
pp.load(new FileInputStream("info.properties"));
4.根据className创建对应对象
/ / 获取到类名
String className = pp.getProperty("className");
// 通过类名字符串获取到Class对象
Class<?> cls = Class.forName(className);
// 通过class对象来创建对象
// Constructor<?> con = cls.getConstructor();
// Object obj = con.newInstance();
// Object obj = new Perosn();
// Object obj = new Dog();
Object obj = cls.newInstance();
5.根据对应的属性赋值给对象
// 给成员变量赋值
// 每个成员变量都需要赋值
// 使用反射获取到类中的所有成员变量
Field[] fields = cls.getDeclaredFields();
for (Field field : fields) {
// 拿到了类中每一个成员变量
// Properties保存中属性值,而且Properties属性名和类的成员变量名一样
String value = pp.getProperty(field.getName());   
// 给成员变量设置值
field.setAccessible(true);
if (field.getType() == int.class) { // int类型
field.setInt(obj, Integer.valueOf(value));
} else {
field.set(obj, value);     } }

以上为个人学习总结,如有错漏,希望能得到沟通以及指正,非常感谢!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值