zoukankan      html  css  js  c++  java
  • Java反射

    Java反射

    反射是Java的高级特性,让原本是静态类型的Java拥有了动态语言的特点。

    Java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为Java语言的反射机制。

    就像镜子一样,反射回来的画面和原本的物体一样。

    反射是Java的重要特性,Java的Spring框架底层就基于反射。

    Class类

    Java中反射的实现是通过Class类表示的,只要获取到Class的对象实例,就可以拿到类的所有信息。

    Class类代表字节码,处于java.lang.reflect包下。

    反射包下包含所有与反射有关的类,如java.lang.reflect.Field

    每个类都会在jvm中编译成字节码,jvm在加载类时对每个对象都会生成一个Class对象,该对象能够在运行时获得类的所有信息,如构造方法、属性、超类等。

    一个类在 JVM 中只会有一个Class实例。

    获取Class对象的三种方法

    /**
    
     * 获取Class对象的三种方式
    
     * 1 Object ——> getClass();
    
     * 2 任何数据类型(包括基本数据类型)都有一个“静态”的class属性
    
     * 3 通过Class类的静态方法:forName(String  className)(常用)
    
     */
    
    

    建立包reflects,在包下创建父类Person,子类Man.

    class Person{
    	String name;
    
    	public Person(String name) {
    		this.name = name;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
        @Override
        public String toString() {
            return "{" +
                " name='" + getName() + "'" +
                "}";
        }
    	
    }
    
    
    class Man extends Person{
    	
    	private int age;
    
    	public Man(String name,int age) {
    		super(name);
    		this.age=age;
    	}
    
    	@Override
    	public String toString() {
    		return "Man [age=" + age + ", name=" + name + "]";
    	}
    }
    

    在主方法中测试Class对象。

    1、通过对象的getClass()方法获取Class对象,该方法是Object类下的方法

    public static void main(String[] args) throws Exception {
    		
    		//通过对象的getClass()方法获取Class对象,该方法是Object类下的方法
    		Man man=new Man("张三",8);
    		Class c1=man.getClass();
    		
    		//打印Class对象
    		System.out.println(c1);//class reflects.Man
    		System.out.println(c1.getName());//reflects.Man
    		System.out.println(c1.getSimpleName());//Man
    		System.out.println(c1.getTypeName());//reflects.Man
        
        	//获取public构造函数数组
    		System.out.println(c1.getConstructors()[0]);//public reflects.Man(java.lang.String,int)
    		
    		//获取超类
    		System.out.println(c1.getSuperclass());//class reflects.Person
    		
    		//获取private字段数组
    		Field[] f=c1.getDeclaredFields();
    		for(Field f0:f) {
    			System.out.println(f0);//private int reflects.Man.age
    		}
    		
    	}
    

    2、通过“静态”的class属性获取Class对象

    	//通过“静态”的class属性获取Class对象
    		Class c2=Man.class;
    		System.out.println(c2);//class reflects.Man
    

    3、通过Class类的静态方法:forName(String className)(常用)

    //通过Class类的静态方法:forName(String  className)(常用)
    		Class c3=Class.forName("reflects.Man");
    		System.out.println(c3);//class reflects.Man
    

    Class对象的实例只有一个,各种方式获取的都是同一个对象。

    通过hashCode()方法测试。

    		System.out.println(c1.hashCode());//31168322
    		System.out.println(c2.hashCode());//31168322
    		System.out.println(c3.hashCode());//31168322
    		//通过hashCode可以看出三种方法生成的对象时同一个
    		
    		System.out.println(c1==c2);//true
    		System.out.println(c1.equals(c3));//true
    

    测试

    测试通过反射创建对象,并且修改方法。

     		Constructor con= c1.getConstructor(String.class,int.class);//获取构造器对象
            Man man2=(Man)con.newInstance("jim",10);//通过构造器对象创建实例
            System.out.println(man2);
    
            //Man [age=10, name=jim]
    
            Class c4=c1.getSuperclass();//获取超类
            Constructor p=c4.getConstructor(String.class);
            Person person=(Person)p.newInstance("hon");
            System.out.println(person);
    
            Method method= c4.getDeclaredMethod("setName", String.class);//获取方法对象
            method.invoke(person, "Tony");//激活方法修改器
            System.out.println(person);
    		
    		//{ name='hon'}
    		//{ name='Tony'}
    
  • 相关阅读:
    把程序的定义与实现部分用头文件与源文件分开
    简单控件的应用(二)—学生管理系统
    Java基础14
    创建插入符、输出不同效果的文字
    Java基础12
    简单控件的应用(一)—prj计算器
    简单的Win 32 Application
    最简单的音乐播放器
    消息处理初步
    基于MFC,在非客户区与客户区利用CButon类创建button
  • 原文地址:https://www.cnblogs.com/cgl-dong/p/12157678.html
Copyright © 2011-2022 走看看