java反射

 一,先看一下反射的概念:

             主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。

             反射是java中一种强大的工具,能够使我们很方便的创建灵活的代码,这些代码可以再运行时装配,无需在组件之间进行源代码链接。但是反射使用不当会成本很高!

 二,反射机制的作用:

              1,反编译:.class-->.java

              2,通过反射机制访问java对象的属性,方法,构造方法等;

 三,在这里先看一下sun为我们提供了那些反射机制中的类:

java.lang.Class;                

java.lang.reflect.Constructor; java.lang.reflect.Field;        

java.lang.reflect.Method;

java.lang.reflect.Modifier;

四,具体功能实现:

//1. 反射机制获取类有三种方法,我们来获取Employee类型
 
//第一种方法:
    Class c1=Class.forName("Employee");
//第二种方法:每个类型都有class属性:
    Class c2=Employee.class;
//第三种方法: 任何一个对象都有getClass方法
    Employee=new Employee();
    Class c3=e.getClass();

    
 //2. 创建对象:利用newInstance;
 Class c=Class.forName("Employee");
 Object o=c.newInstance(); //调用了Employee的无参构造函数
 
 
 //3. 获取属性: 分为所有哦的属性和指定的属性
 //a. 获取所有的属性:
 Class c=Class.forName("java.lang.Integer");
 Field[] fs=c.getDeclaredFields();
 //可变长字符串,存储属性
 StringBuffer sb= new StringBuffer();
 //最外边的public定义 
 sb.append(Modifier.toString(c.getModifiers()) + " class"+ c.getSimpleName()+ "{
");
 //里面的每一个属性
 for(Field field:fs){
     sb.append("	"); //空格
     sb.append(Modifier.toString(field.getDeclaredFields())+" ");//获得属性的修饰符,例如public,static等等  
     sb.append(field.getType().getSimpleName()+"");//属性的类型的名字
     sb.append(field.getName()+";
");//属性的名字+回车 
 }
 sb.append("}");
 System.out.println(sb);
 
 //获取特定的属性
 public static void main(String[] args) throws Exception{
     //获取类
     Class c=Class.forName("User");
     //获取id属性
     Field idF=c.getDeclaredFields("id");
     //实例化这个类赋给o
     Object o=c.newInstance();
     //打破封装
     //使用反射机制可以打破封装性,导致了java对象的属性不安全。
     idF.setAccessible(true);
     //给o对象的id属性赋值"110"  
     idF.set(o,"110");
     System.out.println(idF.get(o));
 }

方法关键字

含义

getDeclaredMethods()

获取所有的方法

getReturnType()

获得方法的放回类型

getParameterTypes()

获得方法的传入参数类型

getDeclaredMethod("方法名",参数类型.class,……)

获得特定的方法

构造方法关键字

含义

getDeclaredConstructors()

获取所有的构造方法

getDeclaredConstructor(参数类型.class,……)

获取特定的构造方法

父类和父接口

含义

getSuperclass()

获取某类的父类

getInterfaces()

获取某类实现的接口

//1. 通过一个对象获得完整的包名和类名
package Reflect;
class Dome{
    。。。
}

class hello{
    public static void main(String[] args){
        Demo demo=new Demo();
        System.out.println(demo.getClass().getName());
    }
}

结果: Reflect.Dome


//2. 实例化Class类对象
packa Reflect;
class Demo{
    ...
}
class hello{
    public static void main(String[] args){
        Class<?> demo1=null;
        Class<?> demo2=null;
        Class<?> demo3=null;
        try{
            demo1=Class.forName("Reflect.Demo");
        }catch(Exception e){
            e.printStackTrace();
        }
        demo2=new Demo().getClass();
        demo3=Demo.class;
        
        System.out.println("类名称   "+demo1.getName());
        System.out.println("类名称   "+demo2.getName());
        System.out.println("类名称   "+demo3.getName());
    }
}

结果:
    类名称   Reflect.Demo
    类名称   Reflect.Demo
    类名称   Reflect.Demo


    
//3. 通过Class实例化其他类的对象
   通过无参构造实例化对象
package Reflect;
class Person{
    public String getName(){
        return name;
    }
    public void setName(String name){
        this.name=name;
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age){
        this.age=age;
    }
    public String toString(){
        return "[" +this.name+" "+this.age+"]";
    }
    private String name;
    private int age;
}

class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        Person per=null;
        try{
            per=(Person) demo.newInstance();
        }catch(InstantiationException e){
            e.printStackTrace();
        }catch(IllegalAccessException e){
            e.printStackTrace();
        }
        per.setName("Rollen");
        per.setAge(20);
        System.out.println(per);
    }
}

结果:[Rollen  20]


但是注意一下,当我们把Person中的默认的无参构造函数取消的时候,比如自己定义只定义一个有参数的构造函数之后,会出现错误:
比如我定义了一个构造函数:
public Person(String name, int age) {
        this.age=age;
        this.name=name;
    }
然后继续运行上面的程序,会出现:
java.lang.InstantiationException: Reflect.Person

    at java.lang.Class.newInstance0(Class.java:340)

    at java.lang.Class.newInstance(Class.java:308)

    at Reflect.hello.main(hello.java:39)

Exception in thread "main" java.lang.NullPointerException

    at Reflect.hello.main(hello.java:47)

所以大家以后再编写使用Class实例化其他类的对象的时候,一定要自己定义无参的构造函数



//4. 通过Class调用其他类的构造函数
package Reflect;
import java.lang.reflect.Constructor;
class Person{
    public Person(){
        
    }
    public Person(String name){
        this.name=name;
    }
    public Person(int age){
        this.age=age;
    }
    public Person(String name, int age){
        this.age=age;
        this.name=name;
    }
    public String getName(){
        return name;
    }
    public int getAge(){
        return age;
    }
    public String toString(){
        return "["+this.name+""+this.age+"]";
    }
    private String name;
    private int age;
}

class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        Person per1=null;
        Person per2=null;
        Person per3=null;
        Person per4=null;
        Constructor<?> cons[]=demo.getConstructors();
        try{
            per1=(Person)cons[0].newInstance();
            per2=(Person)cons[1].newInstance("Rollen");
            per3=(Person)cons[2].newInstance(20);
            per4=(Person)cons[3].newInstance("Rollen",20);
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println(per1);
        System.out.println(per2);
        System.out.println(per3);
        System.out.println(per4);
    }
}

结果:
[null  0]
[Rollen  0]
[null  20]
[Rollen  20]



//5. 返回一个类实现的接口
package Reflect;
interface China{
    public static final String name="Rollen";
    public static int age=20;
    public void sayChina();
    public void sayHello(String name, int age);
}

class Person implements China{
    public Person(){
        
    }
    public Person(String sex){
        this.sex=sex;
    }
    public String getSex(){
        return sex;
    }
    public void sayChina(){
        System.out.println("hello,china");
    }
    public void sayHello(String name,int age){
        System.out.println(name+" "+age);
    }
    private String sex;
}

public class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Class.getName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        
        Class<?> intes[]=demo.getInterfaces();
        for(int i=0; i<intes.length;i++){
            System.out.println("实现的接口 "+ inters[i].getName());
        }
    }
}

结果:   实现的接口   Reflect.China




// 6. 取得其他类中的父类
class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        
        Class<?> temp=demo.getSuperclass();
        System.out.println("继承的父类为: "+temp.getName());
    }
}
结果:继承的父类为:   java.lang.Object


//7. 获得其他类中的全部构造函数
class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        Constructor<?> cons[]=demo.getConstructors();
        for (int i=0; i<cons.length;i++){
            System.out.println("构造方法:"+cons[i]);
        }
    }
}
结果:
    构造方法:  public Reflect.Person()
    构造方法:  public Reflect.Person(java.lang.String)



    
//8. 获取构造函数修饰符
class hello{
    public static void main(String[] args){
        Clss<?> demo=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        Constructor<?> cons[]=demo.getConstructors();
        for(int i=0; i<cons.length;i++){
            Class<?> p[]=cons[i].getParameterTypes();
            System.out.print("构造函数: ");
            int mo=cons[i].getModifiers();
            System.out.print(Modifier.toString(mo)+"");
            System.out.print(cons[i].getName());
            System.out.print("(");
            for(int j=0;j<length;j++){
                System.out.print(p[j].getName()+" arg"+i);
                if(j<p.length-1){
                    System.out.print(",");
                }
            }
            System.out.println("){}");
        }
    }
}

结果:
构造方法:  public Reflect.Person(){}
构造方法:  public Reflect.Person(java.lang.String arg1){}



//9. 取得类的全部属性
class hello{
    public static void main(String[] args){
        Class<?> demo= null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        System.out.println("=====本类属性=====");
        Field[] field=demo.getDeclaredFields();
        for(int i=0;i<field.length;i++){
            //权限修饰符
            int mo=field[i].getModifiers();
            String priv=Modifier.toString(mo);
            //属性类型
            Class<?> type=field[i].getType();
            System.out.println(priv+" "+type.getName()+""+field[i].getName()+";");
        }
        System.out.println("=====实现的接口或父类的属性=====");
        //取得实现的接口或父类的属性
        Field[] field1=demo.getFields();
        for(int j=0;i<field1.length;j++){
            //权限修饰符
            int mo=filed1[j].getModifiers();
            String priv=Modifier.toString(mo);
            //属性类型
            Class<?> type=filed1[j].getType();
            System.out.println(priv+""+type.getName()+""+field1[j].getName()+";");
        }
    }
}

结果:
===============本类属性========================
private java.lang.String sex;
===============实现的接口或者父类的属性========================
public static final java.lang.String name;
public static final int age;



//10.调用其他类中的方法
class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        try{
            demo=Clss.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        try{
            Method method=demo.getMethod("sayChina");
            method.invoke(demo.newInstance());
            
            method=demo.getMethod("sayChina",String.class,int.class);
            method.invoke(demo.newInstance(),"Rollen",20);
        }catch(Exception e){
            e.printStackTrace();
        }
    }
}
结果:
hello ,china
Rollen  20


//11. 调用其他类的set和get方法
class hello{
    public static void main(String[] args){
        Class<?> demo=null;
        Object obj=null;
        try{
            demo=Class.forName("Reflect.Person");
        }catch(Exception e){
            e.printStackTrace();
        }
        try{
            obj=demo.newInstance();
        }catch(Exception e){
            e.printStackTrace();
        }
        setter(obj,"Sex","男",String.class);
        getter(obj,"Sex");
    }
    
    /**
     * @param obj
     *            操作的对象
     * @param att
     *            操作的属性
     * */
    public static void getter(Object obj, String att) {
        try {
            Method method = obj.getClass().getMethod("get" + att);
            System.out.println(method.invoke(obj));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
 
    /**
     * @param obj
     *            操作的对象
     * @param att
     *            操作的属性
     * @param value
     *            设置的值
     * @param type
     *            参数的属性
     * */
    public static void setter(Object obj, String att, Object value,
            Class<?> type) {
        try {
            Method method = obj.getClass().getMethod("set" + att, type);
            method.invoke(obj, value);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }    
}
结果:   男



//12. 1)通过反射取得并修改数组的信息:
import java.lang.reflect.*;
class hello{
    public static void main(String[] args){
        int[] temp={1,2,3,4,5};
        Class<?> demo=temp.getClass().getComponentType();
        System.out.println("数组类型: "+demo.getName());
        System.out.println("数组长度: "+Array.getLength((temp));
        System.out.println("数组的第一个元素:"Array.get(temp,0));
        Array.set(temp,0,100);
        System.out.println("修改之后数组第一个元素为:"+Array.get(temp,0));
    }
}
结果:
数组类型: int
数组长度  5
数组的第一个元素: 1
修改之后数组第一个元素为: 100




//12. 2)反射修改数组大小
class hello{
    public static void main(String[] args) {
        int[] temp={1,2,3,4,5,6,7,8,9};
        int[] newTemp=(int[])arrayInc(temp,15);
        print(newTemp);
        System.out.println("=====================");
        String[] atr={"a","b","c"};
        String[] str1=(String[])arrayInc(atr,8);
        print(str1);
    }
     
    /**
     * 修改数组大小
     * */
    public static Object arrayInc(Object obj,int len){
        Class<?>arr=obj.getClass().getComponentType();
        Object newArr=Array.newInstance(arr, len);
        int co=Array.getLength(obj);
        System.arraycopy(obj, 0, newArr, 0, co);
        return newArr;
    }
    /**
     * 打印
     * */
    public static void print(Object obj){
        Class<?>c=obj.getClass();
        if(!c.isArray()){
            return;
        }
        System.out.println("数组长度为: "+Array.getLength(obj));
        for (int i = 0; i < Array.getLength(obj); i++) {
            System.out.print(Array.get(obj, i)+" ");
        }
    }
}
结果:
数组长度为: 15
1 2 3 4 5 6 7 8 9 0 0 0 0 0 0 =====================
数组长度为: 8
a b c null null null null null
原文地址:https://www.cnblogs.com/zxqstrong/p/5545314.html