Java 反射 新手入门,含详细代码示例

Java 反射 新手入门,含详细代码示例,第1张

Java 反射 新手入门,含详细代码示例

Java 反射 新手入门,含详细代码示例
  • 1、反射的基本概念
  • 2、使用反射 *** 作无参构造方法
  • 3、使用反射 *** 作有参构造方法
  • 4、使用反射 *** 作类的属性
  • 5、使用反射 *** 作类的普通方法

1、反射的基本概念

可以通过反射得到类中的所有内容
  1)属性
  2)无参构造方法
  3)有参构造方法
  4)普通方法
然后说一下到哪一步可以使用反射?
  1)首先我们会创建一个java文件:.java文件
  2)然后会对该java文件进行编译:.class文件 
  3)此时使用jvm将class文件通过类加载加载到内存中。
  这个时候,我们一开始创建的所有java类在内存里面就可以以Class类存在,通过这个Class类就可以得到类中的所有内容。
  1)封装了属性的类使用:Field
  2)封装了构造方法的类使用:Constructor
  3)封装了普通方法的类使用:Method

2、使用反射 *** 作无参构造方法

假如我们创建一个Person的类,首先要知道获取类的3种方式
1)Class c1 = Person.class;
2)Class c2 = new Person().getCLass();
3)Class c3 = Class.forName();

其次,构造新对象现在除了使用new关键词之后,现在还可以使用Class类的newInstance方法来新建对象。
Person p = (Person) c3.newInstance();
使用无参构造方法的代码示例如下:
1)首先创建一个Person类

package com.seleflearn;

public class Person {
    // 2个属性
    private String name;
    private int age;

    // 无参构造函数
    public Person() {};

    // 有参构造函数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 普通方法
    @Override
    public String toString() {
        return this.name + "的年龄是:" + this.age;
    }

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

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

    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

2)然后通过反射创建实例,并给实例设置属性值

package com.seleflearn;

public class test1 {
    public static void main(String[] args) throws Exception{
        // 得到Class
        Class c = Class.forName("com.seleflearn.Person");

        // 使用无参构造方法创建Person的实例
        Person p = (Person) c.newInstance();

        // 设置名称和年龄
        p.setName("张三");
        p.setAge(20);
        System.out.println(p.toString());
    }
}

运行结果如下:

/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=45811:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test4
张三的年龄是:20

Process finished with exit code 0
3、使用反射 *** 作有参构造方法

1)通过getConstructors()方法获取所有的构造方法:
c.getConstructors();
2)通过getConstructor()方法获取有参数构造方法,获取有参构造方法的参数类型,需要使用class形式传递
Constructor cs = c.getConstructor(String.class, int.class);
3)通过有参构造方法可以创建实例:
Person p = (Person) cs.newInstance(“张三”, 20);

使用有残构造方法创建并设置实例的示例如下:

package com.seleflearn;

import java.lang.reflect.Constructor;

public class test2 {
    public static void main(String[] args) throws Exception{
        // 得到Class
        Class c = Class.forName("com.seleflearn.Person");

        // 获取有参数构造方法,获取有参构造方法的参数类型,需要使用class形式传递
        Constructor cs = c.getConstructor(String.class, int.class);

        // 通过有参构造方法创建Person的实例
        Person p = (Person) cs.newInstance("张三", 20);
        System.out.println(p.toString());
    }
}

运行结果如下:

/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=35505:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test2
张三的年龄是:20

Process finished with exit code 0
4、使用反射 *** 作类的属性

1)通过getDeclaredFields()方法得到类的所有属性
c.getDeclaredFields();
2)通过getDeclaredField()方法得到类的属性,该方法的参数是该属性的名称
Field fieldName = c.getDeclaredField(“name”);
Field fieldAge = c.getDeclaredField(“age”);
3)当 *** 作的是私有属性的时候,需要设置可 *** 作权限为true才使用
fieldName.setAccessible(true);
fieldAge.setAccessible(true);
4)给所创建的实例设置属性,有2个参数:第1个参数是类的实例,第2个参数是所需要设置的值
fieldName.set(p, “张三”);
fieldAge.set(p, 20);

使用类的属性来设置实例的示例代码如下:

package com.seleflearn;

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

public class test3 {
    public static void main(String[] args) throws Exception{
        // 得到Class
        Class c = Class.forName("com.seleflearn.Person");

        // 使用无参构造方法创建Person的实例
        Person p = (Person) c.newInstance();

        // 得到name和age属性
        Field fieldName = c.getDeclaredField("name");
        Field fieldAge = c.getDeclaredField("age");
        // 当 *** 作的是私有属性的时候,需要设置可 *** 作权限为true才使用
        fieldName.setAccessible(true);
        fieldAge.setAccessible(true);

        // 给所创建的实例设置属性,有2个参数:第1个参数是类的实例,第2个参数是所需要设置的值
        fieldName.set(p, "张三");
        fieldAge.set(p, 20);

        System.out.println(p.toString());
    }
}

运行结果如下:

/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=46023:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test3
张三的年龄是:20

Process finished with exit code 0
5、使用反射 *** 作类的普通方法

1)通过getDeclaredMethods()来得到所有普通方法
c.getDeclaredMethods()
2)通过getDeclaredMethod()得到指定的普通方法,得到指定的普通方法需要传递2个参数:第1个参数是方法名称,第2个参数是参数类型
Method setName = c.getDeclaredMethod(“setName”, String.class);
Method setAge = c.getDeclaredMethod(“setAge”, int.class);
3)得到普通方法后,使用invoke进行调用,调用invoke需要传递2个参数:第1个参数是该类的实例,第2个参数是该方法所需的参数值
setName.invoke(p, “张三”);
setAge.invoke(p, 20);
4)如果 *** 作的是私有方法,那么也需要先设置 *** 作权限为true
setName.setAccessible(true);
setAge.setAccessible(true);
5)当 *** 作的方法是静态方法时,由于静态方法的调用方式是:类名.静态方法名
所以不需要类的实例,所以将invoke方法的第一个参数设置为null即可
setName.invoke(null, “张三”);
setAge.invoke(null, 20);

使用类的普通方法来设置实例的示例代码如下:

package com.seleflearn;

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

public class test4 {
    public static void main(String[] args) throws Exception {
        // 得到Class
        Class c = Class.forName("com.seleflearn.Person");

        // 使用无参构造方法创建Person的实例
        Person p = (Person) c.newInstance();

        // 得到普通方法需要传递2个参数:第1个参数是方法名称,第2个参数是参数类型
        Method setName = c.getDeclaredMethod("setName", String.class);
        Method setAge = c.getDeclaredMethod("setAge", int.class);

        // 得到普通方法后,使用invoke进行调用,调用invoke需要传递2个参数:第1个参数是该类的实例,第2个参数是该方法所需的参数值
        setName.invoke(p, "张三");
        setAge.invoke(p, 20);
        // 注:如果 *** 作的是私有方法,那么也需要先设置 *** 作权限为true
        // setName.setAccessible(true);
        // setAge.setAccessible(true);

        System.out.println(p.toString());
    }
}

运行结果如下:

/opt/java/jdk-16.0.2/bin/java -javaagent:/opt/idea-IC-212.5457.46/lib/idea_rt.jar=39419:/opt/idea-IC-212.5457.46/bin -Dfile.encoding=UTF-8 -classpath /home/koping/wxp/learn/java/java-web/day20211017/out/production/testReflection com.seleflearn.test4
张三的年龄是:20

Process finished with exit code 0

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/4670571.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-11-06
下一篇 2022-11-06

发表评论

登录后才能评论

评论列表(0条)

保存