Java反射初体验

版权声明:版权所有_lrxu https://blog.csdn.net/u013368397/article/details/80617456

虽然习惯晚睡,但是没想到今天都这么晚了还没睡,o(︶︿︶)o 。

今天从网上看了关于java反射的资料,自己在ide敲了一些代码,望对像我一样的小白有些帮助。好废话不多说,上代码,给你们一个眼神自己体会。


package Reflection_demo;
/**------------------------------------------------*/
/**--@author created by lrxu([email protected])--*/
/**--@date 2018年6月8日上午12:01:31--------------------------*/
/**--@resume---------------------------------------*/
public class Lrxu {
	private static String sex;
	private static int age;
    public static String name = "lrxu25";


    static {
        System.out.println("lrxu静态块");
    }


    public static String getSex() {
		return sex;
	}


	public static void setSex(String sex) {
		Lrxu.sex = sex;
	}


	public static int getAge() {
		return age;
	}


	public static void setAge(int age) {
		Lrxu.age = age;
	}


	public Lrxu() {
        System.out.println("lrxu构造了");
    }
    
	public static String getName() {
		return name;
	}


	public static void setName(String name) {
		Lrxu.name = name;
	}


	//这里要么构造函数里给成员变量赋值 要么像name一样在定义的时候赋值,否则在实例化对象的时候成员变量是没有值的
	//结论:由于new一个对象是存在堆里的,而反射机制是不会从堆里面获取对象的属性值,而是加载jvm中加载过的类的信息。所以这里也就验证了为什么说反射是去发现类的信息而不是类对象的信息
	public Lrxu(String sex,int age) {
//		this.setSex(sex);
//		this.setAge(age);
        System.out.println("lrxu构造了--"+"sex:"+sex+",age:"+age);
    }
}



package Reflection_demo;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**------------------------------------------------*/
/**--@author created by lrxu([email protected])--*/
/**--@date 2018年6月7日下午11:29:55--------------------*/
/**--@resume--理解java反射机制--------------------------*/

/**
 * Java让我们在运行时识别对象和类的信息,主要有2种方式:一种是传统的RTTI,它假定我们在编译时已经知道了所有的类型信息;另一种是反射机制,它允许我们在运行时发现和使用类的信息。
 * RTTI,编译器在编译时打开和检查.class文件
 * 反射,运行时打开和检查.class文件
 * */
public class Reflection {
	public static void main(String[] args) {
		//loadClass();
		getClassFields();
	}
	
	/**获取class的属性*/
	public static void getClassFields() {
		try {
			Lrxu lrxu = new Lrxu("男",25);
			Class clazz = lrxu.getClass();
			Field[] fields = clazz.getDeclaredFields();
			for(Field field :fields) {
				String key = field.getName();
				PropertyDescriptor descriptor = new PropertyDescriptor(key, clazz);//一定要有get、set方法 否则报错
				Method method = descriptor.getReadMethod();// 获得类的public类型的方法
				Object value = method.invoke(lrxu);
				System.out.println(key + ":" + value);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	public static void loadClass() {
		try {
			/**
			object.getClass()和Object.class的区别
			类名.class叫做“类字面量”,因class是关键字, 所以类名.class编译时确定。而getclass()是某个具体的方法来调用,是运行时根据实际实例确定,getClass()是动态而且是final的。 
			例如: 
			String.class 是能对类名的引用取得在内存中该类型class对象的引用,而new String().getClass() 是通过实例对象取得在内存中该实际类型class对象的引用。 */
			System.out.println(Lrxu.name);
			System.out.println(new Lrxu().getClass());
			System.out.println("-Lrxu.name--初始化静态代码块---");
			Class classlr1 = Lrxu.class;
			System.out.println("-Lrxu.class-不会初始化静态代码块----");
			Class clazzlr2 = Class.forName("Reflection_demo.Lrxu");//字符串格式  包名+类名  否则会 classnotfound
			
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}

猜你喜欢

转载自blog.csdn.net/u013368397/article/details/80617456
今日推荐