反射、枚举

文章详细介绍了Java的反射机制,包括在运行时获取类的属性、方法和构造器的能力,以及其在开发通用框架中的作用。同时,提到了反射带来的灵活性和扩展性,但也指出其可能导致的效率降低和代码维护困难。示例代码展示了如何通过反射访问私有成员和调用私有方法。
摘要由CSDN通过智能技术生成
  1. 反射的定义:Java的反射机制是在运行状态中,都能对任意的类拿到这个类的所有属性,从而对其进行相应的修改;
  2. 用途:在日常第三方应用开发中,可以通过反射机制来获取某个类的私有成员变量或是方法;主要是用来开发各种通用框架;
  3. 优缺点:

        优

        1) 对于任意一个类,都能够知道这个类的所有属性和方法;

            对于任意一个对象,都能够调用它的任意一个方法;

        2) 增加程序的灵活性和扩展性,降低耦合性,提高自适应能力

        3) 反射已经运用在了很多流行框架如:Struts、Hibernate、Spring 等等。

        缺        

        1) 使用反射会有效率问题。会导致程序效率降低。

            具体参考这里:http://www.imooc.com/article/293679

        2) 反射技术绕过了源代码的技术,因而会带来维护问题。反射代码比相应的直接代码更复杂 

4.反射相关的类:获取类的相关方法:

方法用途
getClassLoader()获得类的加载器
getDeclaredClasses()返回一个包含该类中所有类和接口类的对象数组
forName(String className)根据类名返回类对象
newInstance()创建类的实例
getName()获得类的完整路径名字

获取类中属性的相关的方法

方法用途
getField(String name)获得某个公有的属性对象
getFields()获得所有公有的属性对象
getDeclaredField(String name)获得某个属性对象
getDeclaredFields()获得所有属性对象

获取类中注解相关的方法(了解)

 获得类中构造器相关的方法(以下方法返回值为Constructor相关)

 获得类中方法相关的方法(以下方法返回值为Method相关)

方法用途
getMethod(String name, Class... parameterTypes)获得该类某个公有的方法
getMethods()获得该类所有公有的方法
getDeclaredMethod(String name, Class... parameterTypes)获得该类某个方法
getDeclaredMethods()

获得该类所有方法

  1. 反射程序示例  

                第一步自然是要获得当前要反射的类的Class对象,这里有三种

//第一种,使用 Class.forName("类的全路径名"); 静态方法。
//前提:已明确类的全路径名。
//第二种,使用 .class 方法。
//说明:仅适合在编译前就已经明确要操作的 Class
//第三种,使用类对象的 getClass() 方法

//以下是代码示例


class Student{
    //私有属性name
    private String name = "bit";
    //公有属性age
    public int age = 18;
    //不带参数的构造方法
    public Student(){
        System.out.println("Student()");
    }

    private Student(String name,int age) {
        this.name = name;
        this.age = age;
        System.out.println("Student(String,name)");
    }

    private void eat(){
        System.out.println("i am eat");
    }

    public void sleep(){
        System.out.println("i am pig");
    }
    private void function(String str) {
        System.out.println(str);
    }
    @Override
    public String toString() {
        return "Student{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
    }
}

public class TestDemo {
    public static void main(String[] args) {
    /*
    1.通过getClass获取Class对象
    */
    Student s1 = new Student();
    Class c1 = s1.getClass();
    
    /*
    2.直接通过 类名.class 的方式得到,该方法最为安全可靠,程序性能更高
    这说明任何一个类都有一个隐含的静态成员变量 class
    */
    Class c2 = Student.class;
    
    /*
    3、通过 Class 对象的 forName() 静态方法来获取,用的最多,
    但可能抛出 ClassNotFoundException 异常
    */
    Class c3 = null;
    try {
        //注意这里是类的全路径,如果有包需要加包的路径
        c3 = Class.forName("Student");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
    //一个类在 JVM 中只会有一个 Class 实例,即我们对上面获取的
    //c1,c2,c3进行 equals 比较,发现都是true
    System.out.println(c1.equals(c2));
    System.out.println(c1.equals(c3));
    System.out.println(c2.equals(c3));
    }
}

        在别的包里使用反射机制来获取Studentlei中的属性对象,构造方法和方法等;

//所有和反射相关的包都在 import java.lang.reflect 包下面
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectClassDemo {
    // 创建对象
    public static void reflectNewInstance() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得学生对象:"+student);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    // 反射私有的构造方法 屏蔽内容为获得公有的构造方法
    public static void reflectPrivateConstructor() {
        try {
            Class<?> classStudent = Class.forName("Student");
            //注意传入对应的参数
            Constructor<?> declaredConstructorStudent = 
                classStudent.getDeclaredConstructor(String.class,int.class);
            //Constructor<?> declaredConstructorStudent = classStudent.getConstructor();
            //设置为true后可修改访问权限    
            declaredConstructorStudent.setAccessible(true);
            Object objectStudent = declaredConstructorStudent.newInstance("张三",15);
            //Object objectStudent = declaredConstructorStudent.newInstance();
            Student student = (Student) objectStudent;
            System.out.println("获得私有构造哈数且修改姓名和年龄:"+student);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    // 反射私有属性
    public static void reflectPrivateField() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Field field = classStudent.getDeclaredField("name");
            field.setAccessible(true);
            //可以修改该属性的值
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            field.set(student,"小明");
            String name = (String) field.get(student);
            System.out.println("反射私有属性修改了name:"+ name);
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    // 反射私有方法
    public static void reflectPrivateMethod() {
        try {
            Class<?> classStudent = Class.forName("Student");
            Method methodStudent =classStudent.getDeclaredMethod("function",String.class);
            System.out.println("私有方法的方法名为:"+methodStudent.getName());
            //私有的一般都要加
            methodStudent.setAccessible(true);
            Object objectStudent = classStudent.newInstance();
            Student student = (Student) objectStudent;
            methodStudent.invoke(student,"我是给私有的function函数传的参数");
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    public static void main(String[] args) {
        //reflectNewInstance();
        //reflectPrivateConstructor();
        //reflectPrivateField();
        reflectPrivateMethod();
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值