原文出处: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 }
反射“私有”的构造函数和反射得到类中所有的构造函数
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 }
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);