反射(2020年11月19日10:09:31)

原文出处:https://blog.csdn.net/ju_362204801/article/details/90578678

Java中创建对象大概有这几种方式:

1、使用new关键字:这是我们最常见的也是最简单的创建对象的方式

2、使用Clone的方法:无论何时我们调用一个对象的clone方法,JVM就会创建一个新的对象,将前面的对象的内容全部拷贝进去

3、使用反序列化:当我们序列化和反序列化一个对象,JVM会给我们创建一个单独的对象

上边是Java中常见的创建对象的三种方式,其实除了上边的三种还有另外一种方式,就是接下来我们要讨论的 “反射”

1.什么是反射:反射就是把Java类中的各个部分,映射成一个个的Java对象,拿到这些对象后可以做一些事情。

一个类有:成员变量,方法,构造方法,等信息,利用反射技术咱们可以把这些组成部分映射成一个个对象。

2.反射能用来做什么?

比如在通过框架写项目时,通过反射创建某个类的实例对象等等;

3.怎样得到想反射的类?

反射是对一个类进行解剖,想解剖一个东西,前提是首先你得拿到这个东西

获取Class对象的三种方式

(1)通过类名获取      类名.class   

(2)通过对象获取      对象名.getClass()

(3)通过全类名获取    Class.forName(全类名)

一般都会用第三种。

咱们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件。Java是面向对象的语言,一切皆对象,

所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class,大家可以去AIP里看一下这个类

解剖类

我们知道一个类里一般有构造函数、方法、成员变量(字段/属性)这三部分组成

翻阅API文档,可以看到

Class对象提供了如下常用方法:

public Constructor getConstructor(Class<?>…parameterTypes)

public Method getMethod(String name,Class<?>… parameterTypes)

public Field getField(String name)

public Constructor getDeclaredConstructor(Class<?>…parameterTypes)

public Method getDeclaredMethod(String name,Class<?>… parameterTypes)

public Field getDeclaredField(String name)

这些方法分别用于帮咱们从类中解剖出构造函数、方法和成员变量(属性)。

然后把解剖出来的部分,分别用Constructor、Method、Field对象表示。

4.通过构造方法,传值:

 1 package reflect;
 2 
 3 public class ReflectEntity {
 4 
 5     public String name;
 6     public String sex;
 7     public String age;
 8 
 9     public ReflectEntity() {
10         System.out.println("这是ReflectEntity类无参数构造方法");
11     }
12 
13     public ReflectEntity(String name, String sex, String age) {
14         this.name = name;
15         this.sex = sex;
16         this.age = age;
17         System.out.println("这是ReflectEntity类有参数构造方法,姓名:"+name+",性别:"+sex+",年龄"+age);
18     }
19     //私有构造方法
20     private ReflectEntity(String name) {
21         this.name = name;
22     }
23 
24 
25     public String getName() {
26         System.out.println("这是name属性的get方法,姓名:"+name);
27         return name;
28     }
29 
30     public void setName(String name) {
31         this.name = name;
32         System.out.println("这是name属性的set方法,姓名:"+name);
33     }
34 
35     public String getSex() {
36         return sex;
37     }
38 
39     public void setSex(String sex) {
40         this.sex = sex;
41     }
42 
43     public String getAge() {
44         return age;
45     }
46 
47     public void setAge(String age) {
48         this.age = age;
49     }
50 }
 1 package reflect;
 2 
 3 import org.junit.Test;
 4 
 5 import java.lang.reflect.Constructor;
 6 
 7 public class ReflectEntityTest {
 8    //反射无参的构造函数
 9    @Test
10    public void Test1() throws Exception{
11       //得到字节码文件
12       Class cla = Class.forName("reflect.ReflectEntity");//代表ReflectEntity类在内存中的字节码对象
13       Constructor c = cla.getConstructor(null);//得到ReflectEntity类的无参构造方法,可以创建对象
14       c.newInstance(null);
15 
16       //得到ReflectEntity类的有参数构造方法,可以创建对象
17       Constructor cc = cla.getConstructor(String.class,String.class,String.class);
18       cc.newInstance("王五","男","22");
19    }
20 
21 }
View Code

 

反射“私有”的构造函数和反射得到类中所有的构造函数

 1 package reflect;
 2 
 3 import org.junit.Test;
 4 
 5 import java.lang.reflect.Constructor;
 6 
 7 
 8 public class ReflectEntityTest {
 9    //反射无参的构造函数
10    @Test
11    public void Test1() throws Exception{
12       //得到字节码文件
13       Class cla = Class.forName("reflect.ReflectEntity");//代表ReflectEntity类在内存中的字节码对象
14       Constructor c = cla.getConstructor(null);//得到ReflectEntity类的无参构造方法,可以创建对象
15       c.newInstance(null);
16 
17       //得到ReflectEntity类的有参数构造方法,可以创建对象
18       Constructor cc = cla.getConstructor(String.class,String.class,String.class);
19       cc.newInstance("王五","男","22");
20       //通过反射得到私有构造方法,并赋值
21       Constructor ccc = cla.getDeclaredConstructor(String.class);
22       //想访问 Field、 Method 和 Constructor 的私有对象,均需 setAccessible
23       ccc.setAccessible(true);
24       ccc.newInstance("私有构造方法");
25 
26       //通过反射得到所有构造方法
27       Constructor[]  cccs = cla.getDeclaredConstructors();
28       for (Constructor  cs: cccs)
29       {
30          System.out.println(cs);
31       }
32    }
33 
34 }

5.反射类中的方法

 1 package reflect;
 2 
 3 public class ReflectEntity {
 4 
 5     public String name = "王五";
 6     public String sex = "男";
 7     public String age = "29";
 8 
 9     public ReflectEntity() {
10         System.out.println("这是ReflectEntity类无参数构造方法");
11     }
12 
13     public ReflectEntity(String name, String sex, String age) {
14         this.name = name;
15         this.sex = sex;
16         this.age = age;
17         System.out.println("这是ReflectEntity类有参数构造方法,姓名:"+name+",性别:"+sex+",年龄"+age);
18     }
19     //私有构造方法
20     private ReflectEntity(String name) {
21         this.name = name;
22         System.out.println("这是私有构造方法:"+name);
23     }
24     public void m1(){
25         System.out.println("m1");
26     }
27 
28     public void m2(String age){
29         System.out.println("m2,年龄:"+age);
30     }
31     public String m3(String name){
32         System.out.println("m3"+name);
33         return "return m3";
34     }
35 
36     public String getName() {
37         System.out.println("这是name属性的get方法,姓名:"+name);
38         return name;
39     }
40 
41     public void setName(String name) {
42         this.name = name;
43         System.out.println("这是name属性的set方法,姓名:"+name);
44     }
45 
46     public String getSex() {
47         return sex;
48     }
49 
50     public void setSex(String sex) {
51         this.sex = sex;
52     }
53 
54     public String getAge() {
55         return age;
56     }
57 
58     public void setAge(String age) {
59         this.age = age;
60     }
61 }
View Code
 1   @Test
 2    public void Test2() throws Exception{
 3       // 反射类中方法public vlid m1()
 4       Class cla = Class.forName("reflect.ReflectEntity");
 5       ReflectEntity ref = (ReflectEntity) cla.newInstance();
 6       Method met1 = cla.getMethod("m1",null);
 7       met1.invoke(ref,null);
 8 
 9       //public void m2(String age)
10       Method met2 = cla.getMethod("m2",String.class);
11       met2.invoke(ref,"22");
12 
13       // public String m3(String name)
14       Method met3 = cla.getMethod("m3",String.class);
15       String str= (String) met3.invoke(ref,"多多");
16       System.out.println(str);
17    }

6.反射类中的属性字段

 1    @Test
 2    public void Test3() throws Exception{
 3       //反射类中的属性字段
 4       Class cla = ReflectEntity.class;
 5       ReflectEntity ref = (ReflectEntity) cla.newInstance();
 6       Field fie = cla.getField("name");
 7       String name = (String) fie.get(ref);
 8       System.out.println(name);
 9 
10       //更改name的值
11       fie.set(ref,"钱六");
12       System.out.println(ref.name);

6

我是代码搬运工!!!
原文地址:https://www.cnblogs.com/FanKL/p/14004447.html