java动态性之——反射机制reflection

动态语言

 ——程序在运行的时候可以改变程序的结构或者变量类型,典型的语言:javascript,pyhton,ruby。

如下面这段javascript代码:

function test(){

   var a=3;

  var b=4;

  alert(a+b);

 }

C,C++,java并不是动态语言,但是java具有一定的动态性,我们可以通过反射机制或者字节码的操作获得类型动态语言的特性,java的动态性让java编程更加的灵活!

1 —— java的反射机制 reflection

反射的意思就是程序在运行期间动态的获取类中的属性,包括包括其modifiers(修饰符),fields(属性),methods(方法),Annotation(注解),那么什么叫动态的获取呢?

在类加载的时候,jvm会给每个类的创建一个Class类型的类对象(一个类只产生一个类对象),而这个类对象中包含类的全部信息,我们就可以通过这个类对象获得类的全部结构。这个对象就好像是一面镜子,透过这个镜子可以看到类的结构,这就称之为反射!

2 ——  反射的三种方式

Class clazz= Class.forName("");  //参数为类的全路径

类名.class

对象.getClass

3 —— 反射机制的常见作用

反射获取到了类的class对象,那么它到底应该怎么使用呢?

首先我们创建一个类

public class Student {

	private String name;
	
	private String age;
	
	private String sex;

	
	public Student() {
		
	}
	
	public String getName() {
		return name;
	}

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

	public String getAge() {
		return age;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getSex() {
		return sex;
	}

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

	public Student(String name,String age,String sex) {
		this.name = name;
		this.age = age;
		this.sex = sex;
	}
	
	public void study() {
		System.out.println("学生学习");
	}
}

再创建一个测试类

package com.turing.test.jdbc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo02 {
    
    public static void main(String[] args) throws Exception {
        testField();
        testConstructor();
        testMethod();
    }
    
    /**
     * 测试反射获取属性
     */
    public static void testField() throws Exception{
        //第一种反射获取class对象
        Class clazz = Class.forName("com.turing.test.jdbc.Student");
        //获得他的全部属性
        Field[] fileds = clazz.getDeclaredFields();
        //获得他指定的属性
        Field name = clazz.getDeclaredField("name");
        System.out.println(name);
        
    }
    
    /**
     * 测试反射获取构造方法
     */
    public static void testConstructor() throws Exception{
        //第二种反射获取class对象
        Class clazz = com.turing.test.jdbc.Student.class;
        //获得他的全部的构造器
        Constructor[] constructors = clazz.getDeclaredConstructors();
        //获得他的无参构造器
        Constructor constructorNoParameter = clazz.getDeclaredConstructor(null);
        System.out.println(constructorNoParameter);
        //获得他的有参构造器
        Constructor constructor = clazz.getDeclaredConstructor(String.class,String.class,String.class);
        System.out.println(constructor);
        System.out.println(constructor.getParameterCount());//参数个数
        
    }
    
    /**
     * 测试反射获取方法
     */
    public static void testMethod() throws Exception {
        //第三种反射获取class对象
        Student stu = new Student();
        Class clazz = stu.getClass();
        //获取全部的方法
        Method[] methods = clazz.getDeclaredMethods();
        //获得某个指定的方法
        Method method = clazz.getDeclaredMethod("study", null);
        System.out.println(method);
    }
}
第二个测试类

package com.turing.test.jdbc;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

/**
 *  反射实例化对象
 * @author lvdefu
 *
 */
public class Demo03 {
    
    public static void main(String[] args) throws Exception {
        testReflection();
    }
    
    @SuppressWarnings("all")
    public static void testReflection() throws Exception {
         Class<Student> clazz = (Class<Student>) Class.forName("com.turing.test.jdbc.Student");
         
         //反射获取他的实例化对象
         Student stu = clazz.newInstance(); //这个方法默认调用它的无参构造器
         
         //反射调用有参数的构造方法
         Constructor<Student> constructor = clazz.getDeclaredConstructor(String.class,String.class,String.class);
         Student stu1 = constructor.newInstance("LDF","28","男"); //调用有参数构造器
         System.out.println("名字:"+stu1.getName()+"年龄:"+stu1.getAge()+"性别:"+stu1.getSex());
         
     
         //通过反射API调用方法
         Student stu2 = clazz.newInstance();
         Method setNameMethod = clazz.getDeclaredMethod("setName",String.class);
         setNameMethod.invoke(stu2, "GH");//invoke 代表激活这个方法
         Method getNameMethod = clazz.getDeclaredMethod("getName", null);
         String a = (String)getNameMethod.invoke(stu2, null);
         System.out.println(a);
         
         //通过反射API设置他的属性
         Student stu3 = clazz.newInstance();
         Field f = clazz.getDeclaredField("name");
         //设置私有制属性权限的验证
         f.setAccessible(Boolean.TRUE);
         //设置他属性的值
         f.set(stu3, "BWT");
         //第一种获取值方法
         System.out.println(stu3.getName());
         //通过反射读取属性的值
         System.out.println(f.get(stu3));
         
    }
}
 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值