reflect

博客围绕Java展开,介绍了反射机制的相关操作。包括新建Person实体类,获取类对象和类中所有方法,使用反射实例化对象,利用反射获取构造器并实例化对象,以及使用反射获取类对象并调用类中的方法。

1.新建一个Person实体类

package reflect;

/**
 * 使用当前类测试反射机制
 */
public class Person {
    private String name = "张三";
    private int age = 22;

    public Person() {
    }

    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void sayHello(){
        System.out.println(name+":大家好!");
    }
    public void sayHi(){
        System.out.println(name+":嗨!,我今年"+age);
    }

    public void say(String name){
        System.out.println(this.name+":你好!"+name);
    }

    public void say(String name,int age){
        System.out.println(this.name+":你好!"+",你今年"+age+"了吗?");
    }

    @Override
    public String toString() {
        return "Person{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

2. 获取一个类的类对象和类中所有方法

package reflect;

import java.lang.reflect.Method;
import java.util.Scanner;

/**
 * 反射
 * 反射是java中的一套动态机制,允许我们的程序在运行期间在确定对象的实例化,属性
 * 的操作以及方法的调用.
 * 反射可以提高代码的灵活性,但是也会带来较慢的运行速度和更多的资源开销.所以不能
 * 过渡依赖反射.
 *
 */
public class ReflectDemo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        /*
            反射的第一步是获取要操作的类的类对象,即:class的实例
            JVM中每个被加载的类都有且只有一个Class的实例与之对应,通过这个类对象
            可以了解它表示的这个被加载的类的一切信息(类名,有哪些属性,方法,构造器等)
            并可以进行响应的操作.

            获取一个类的类对象主要方式为:
            1:类名.class . 例如:
            Class cls = String.class;//获取String的类对象
            Class cls = int.class//获取int的类对象,基本类型也有类对象

            2:Class.forName(String className).例如:
            Class cls = Class.forName("java.lang.String");
            基本类型不能用这样的方式被加载

            3:类加载器ClassLoader
         */
        //获取字符串的类对象
//        Class cls = String.class;
//        Class cls = Class.forName("java.lang.String");
        /*
            java.util.HashMap
            java.util.ArrayList
            java.io.FileOutPutStream
            java.io.RandomAccessFile
            reflect.Person
         */
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入一个类名:");
        String className = scan.nextLine();
        Class cls = Class.forName(className);
        String name = cls.getName();
        System.out.println("字符串的类对象名:"+name);

        //获取Class所表示类的所有方法(不包含私有方法)
        Method[] methods = cls.getMethods();
        System.out.println("字符串的所有方法总计:"+methods.length+"个");
        for(Method method : methods){
            System.out.println(method.getName());
        }
    }
}

3.使用反射机制实例化对象

package reflect;

import java.util.ArrayList;
import java.util.Scanner;

/**
 * 使用反射机制实例化对象
 */
public class ReflectDemo2 {
    public static void main(String[] args) throws Exception {
        ArrayList list = new ArrayList();
        System.out.println(list);

        //1加载要实例化的类对象
        Scanner scan = new Scanner(System.in);
        System.out.println("请输入一个类名:");
        String className = scan.nextLine();
        Class cls = Class.forName(className);

        //2实例化
        Object obj = cls.newInstance();
        System.out.println(obj);

    }
}

4.利用反射机制获得一个类的构造器并实例化对象

package reflect;

import java.lang.reflect.Constructor;

/**
 * 使用不同的构造器实例化参数
 */
public class ReflectDemo3 {
    public static void main(String[] args) throws Exception {
        Person p1 = new Person();
        System.out.println(p1);

        Person p2 = new Person("苍老师",55);
        System.out.println(p2);

        //使用反射
        Class cls = Class.forName("reflect.Person");

        //通过类对象获取对应的构造器
        Constructor c = cls.getConstructor();//获取无参的构造器
        Object obj = c.newInstance();//创建一个实例
        System.out.println(obj);

        //获取有参构造器
        Constructor c1 = cls.getConstructor(String.class,int.class);
        Object obj1 = c1.newInstance("苍老师",55);
        System.out.println(obj1);
    }
}

5.使用反射机制获取一个类对象并调用一个类中的方法

package reflect;

import java.lang.reflect.Method;

/**
 * 使用反射机制调用构造方法
 */
public class ReflectDemo4 {
    public static void main(String[] args) throws Exception {
        Person p = new Person();
        p.sayHello();

        //使用反射
        Class cls = Class.forName("reflect.Person");
        Object o = cls.getConstructor().newInstance();//实例化person
        //调用sayHello方法
        Method m = cls.getMethod("sayHello");
        m.invoke(o);// o.sayHello

        p.say("李四");//调用有参方法
        //第二个参数开始就是方法的参数类型,顺序,个数,类型必须与方法定义一致
        Method m2 = cls.getMethod("say", String.class);
        m2.invoke(o,"李四");


        p.say("李四",22);

        Method m3 = cls.getMethod("say", String.class, int.class);
        m3.invoke(o,"李四",22);


    }
}

03-19
### 关于 Reflect 对象 Reflect 是 ECMAScript 6 中引入的一个内置对象,用于提供一种更一致的方式来操作对象及其属性[^1]。它包含了多个静态方法,这些方法可以用来执行常见的反射操作,比如设置属性、删除属性、定义属性以及调用函数等。 #### 主要功能 Reflect 提供的方法与 Proxy 的陷阱(traps)一一对应,这使得它们可以在代理模式下协同工作。以下是 Reflect 的一些主要方法: - `Reflect.get(target, propertyKey, receiver)` 获取目标对象上指定键的值。如果存在 getter,则会调用该 getter[^2]。 - `Reflect.set(target, propertyKey, value, receiver)` 设置目标对象上的某个属性的值,并返回布尔值表示是否成功完成此操作。 - `Reflect.deleteProperty(target, propertyKey)` 删除目标对象中的特定属性并返回布尔值指示删除成功与否。 - `Reflect.construct(target, argumentsList[, newTarget])` 使用给定的新目标创建一个新的实例 (类似于通过 `new target(...args)` 创建)。 - `Reflect.apply(target, thisArgument, argumentsList)` 调用一个函数并将参数列表应用到这个上下文中。 - `Reflect.defineProperty(target, propertyKey, attributes)` 定义新属性或者修改现有属性,并返回一个布尔值表明操作是否成功。 - `Reflect.has(target, propertyKey)` 判断某对象是否有对应的属性名,相当于使用运算符 `in` 进行检测。 - `Reflect.isExtensible(target)` 检查目标对象是否可扩展,即能否添加新的属性。 - `Reflect.preventExtensions(target)` 阻止进一步向目标对象添加任何新属性,并返回布尔值来确认状态改变的结果。 - `Reflect.getOwnPropertyDescriptor(target, propertyKey)` 返回指定属性的描述符;如果没有找到这样的直接属性则返回 undefined。 - `Reflect.ownKeys(target)` 返回由目标自身的所有属性组成的数组,包括不可枚举的属性和符号类型的属性。 #### 示例代码 下面是一个简单的例子展示如何利用 `Reflect` 来管理对象的行为: ```javascript const obj = {}; console.log(Reflect.set(obj, 'name', 'John')); // true console.log(obj.name); // John // 尝试访问不存在的 key let result = Reflect.get(obj, 'age'); if (!result) { console.log('Age not defined'); // Age not defined } // 移除属性 Reflect.deleteProperty(obj, 'name'); console.log(obj.hasOwnProperty('name')); // false ``` #### 结论 通过上述介绍可以看出,Reflect 不仅简化了许多原本复杂的语法结构,还增强了程序控制能力,特别是在元编程领域有着广泛的应用前景。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值