java学习--简单学习反射

反射

反射:框架设计的灵魂 ,动态语言的关键 (框架:简化编码----用框架不用使用反射)学习反射理解框架运行
反射:将类中各部分封装为其他对象

好处:
  1. 在程序的运行过程中操作这些对象
    例如:eclipse 软件中
    你在编写程序是建立了一个String str = “abs” 对象
    你可以str. 直接调用许多方法
    为什么能调用呢:软件已经将 String 这个编译出来的class文件中的所有方法提取出去封装为对象 在展示出来 并且eclipse程序在运行过程中
  2. 可以解耦,提高程序的可扩展性

Class对象功能:

获取方法:

  1. 获取成员变量们 java.lang.reflect.Field:代表类的成员变量
    (1)Field[] getField()
    (2)Field getField(String name)
    (3)Field[] getDeclaredFields()
    (4)Field getDeclaredFields(String name)
  2. 获取构造方法们 java.lang.reflect.Constructor:代表类的构造方法
    (1)Constructor<?>[] getConstructor()
    (2)Constructor getConstructor(类<?>…paramterType)
  3. 获取成员方法们: java.lang.reflect.Method:代表类的方法
    (1)Method[] getDeclaredMethods()
    (2)Method getDeclaredMethod(String name,类<?>…parmeterTypes)
  4. 获取类名 java.lang.Class
    (1)String getName()

Filed:成员变量

  • 操作:
  • 获取:
    Filed.get()
    修改:
    Filed.set()

Constructor:构造方法
创建对象
T newInstance()
若果使用空参构造方法创建对象,可以简化

获取Class对象

java代码在计算机运行中有三个状态:

  1. 源代码状态:java代码通过javac编译为class文件(类的加载)
  2. Class类对象阶段:class文件通过类加载器分解为成员变量,构造器,成员方法 的类对象(类的连接)
  3. 运行时阶段 :调用对象,创建对象(类的初始化)
  • 第一阶段:通过Class.forName(“全类名”) 多用于配置文件,将类名定义在配置文件中,读取文件,加载类
  • 第二阶段:类名.class 多用于参数的传递
  • 第三阶段:对象.getclass 获取
    从程序的运行来看反射
    正常:导包----->实例化----->获取对象
    反射:实例化的对象 ------>getclass()方法 ---------->得到完整的类的包名

得出结论:同一个字节码文件(.class) 在一次程序运行中,只被加载一次,无论通过哪种方式获取的Class对象都是同一个。
一个class对象队形的是一个加载到JVM中的一个.class文件

使用Class对象
获取功能
1.获取成员变量们
2.获取构造方法们
3.获取成员方法们
4.获取类名

案例

反射案例:写一个”框架”,不改变该类的任何代码,可以创建任意类的对象,并执行其中任意方法

  1. 需要的创建的对象的全类名和需要执行的方法定义在配置文件中

  2. 创建配置文件的对象 (例如:Propertiees 配置文件)
    Properties pro = new Properties();

  3. 找到要加载的配置文件
    需要类加载器中找到指定资源并转换为流的方法
    ClassLoader classLoader =本文件名.class.getClassloader();
    InputStream in = classLoader.getResouceAsStream(“配置文件名”)

  4. 配置文件对象的方法,启动加载配置文件
    (例如 pro.load(is))将配置文件中的内容,转换为集合存放在pro对象中

  5. 获取配置文件中定义的数据
    String className = pro.getProperty(“***”);

  6. 加载该类进内存
    Class cls = Class.forName(className);

  7. 创建对象
    Object obj = cls.newInstance;

  8. 获取方法对象
    Method method = cls.getMethod(“方法名”);

  9. 执行方法
    method.invoke(obj);

反射的一些基本方法的使用
/*
getConstructor()获取构造器
getDeclaredConstructors()获取所有构造器

getModifiers()获取访问权限
newInstance()实例化
getParameterTypes()返回所有参数类型
*/
try {
		//1.获取到类,通过类名得到类
			Class cls = User.class;
		//2.获取类的构造方法,获取指定构造器时,需要填写对应的参数类型的类
			//获取无参构造方法
			Constructor cons = cls.getConstructor();
			//获取带参构造方法
			Constructor con = cls.getConstructor(String.class,String.class,int.class);
			
			//获取到构造方法的访问权限
			System.out.println("构造方法的访问权为:"+Modifier.toString(con.getModifiers()));
			
			//通过带参构造方法实例化
			User user = (User) con.newInstance("zhan","1236",8000);
			System.out.println("用户名为:"+user.getName()+" ,密码为:"+user.getPassword());
			
			//获取到所有的构造方法
			//Constructor[] cons = clazz.getConstructors();
			//忽略权限
			Constructor[] co = cls.getDeclaredConstructors();
			for (Constructor c : co) {
				System.out.print(Modifier.toString(c.getModifiers())+" ");
				//获取构造方法名称
				System.out.print(c.getName()+"(");
				//获取所有的参数
				Class[] parType = c.getParameterTypes();
				if(parType.length!=0){
					for (int i=0;i<parType.length;i++) {
						if(i<parType.length-1){
							//获取到参数名称
							System.out.print(parType[i].getSimpleName()+",");
						}else{
							System.out.println(parType[i].getSimpleName()+"){}");
						}
					}
				}else{
					System.out.println("){}");
					//实例化之前开启忽略
					c.setAccessible(true);
					Object obj = c.newInstance();
					System.out.println(obj);
				}
			}
		} catch (Exception e) {
			System.out.println(e.getMessage());
		}
try {
			Class cls = User.class;
			Constructor con = clazz.getConstructor(int.class,String.class,String.class,int.class);
			Object obj = con.newInstance(1001,"sasd","666666",88888);
			//获取单个属性
			Field field = clazz.getDeclaredField("name");
			field.setAccessible(true);
			//为对应的对象属性赋值,属性名叫name
			field.set(obj, "张三");
			//获取属性值
			System.out.println(field.get(obj));
			
			System.out.println("==================获取所有的属性======================");
			Field[] fields = clazz.getDeclaredFields();
			for (Field f : fields) {
				System.out.print(Modifier.toString(f.getModifiers())+" ");
				//获取属性类型
				System.out.print(f.getType().getSimpleName()+" ");
				System.out.println(f.getName()+";");
				f.setAccessible(true);
				//获取所有属性值
				System.out.println(f.getName()+"的属性值为===="+f.get(obj));
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
try {
			Class clazz = User.class;
			//实例化对象
			Constructor con = clazz.getDeclaredConstructor(int.class,String.class,String.class,int.class);
			con.setAccessible(true);
			//创建实例
			Object obj = con.newInstance(1001,"吕布","123",50000);
			//获取一个方法
			Method method = clazz.getDeclaredMethod("print");
			System.out.println(Modifier.toString(method.getModifiers()));
			method.setAccessible(true);
			//执行方法,调用invoke方法  ,执行的是哪个对象的方法,对象作为参数
			method.invoke(obj);   //无参无返回值
			
			Method method1 = clazz.getDeclaredMethod("setPassword", String.class);
			method1.invoke(obj, "diaochan");  //调用设置密码的方法,带参数
			
			Method method2 = clazz.getDeclaredMethod("getPassword");
			Object password = method2.invoke(obj);  //调用获取密码的方法,带返回值
			System.out.println("新设置的密码为:"+password);
			
			System.out.println("=======================获取所有方法========================");
			Method[] methods = clazz.getDeclaredMethods();
			for (Method m : methods) {
				System.out.print(Modifier.toString(m.getModifiers())+" ");
				//获取返回值类型
				System.out.print(m.getReturnType().getSimpleName()+" ");
				System.out.print(m.getName()+"(");
				//获取所有参数类型
				Class[] type = m.getParameterTypes();
				if(type.length!=0){
					for (int i = 0; i < type.length; i++) {
						if(i<type.length-1){
							System.out.print(type[i].getSimpleName()+", ");
						}else{
							System.out.println(type[i].getSimpleName()+"){}");
						}
					}
				}else{
					System.out.println("){}");
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值