这篇Java反射机制太经典!不看后悔!
作者:互联网
01
概念
反射是Java的特征之一,是一种间接操作目标对象的机制,核心是JVM在运行的时候才动态加载类,并且对于任意一个类,都能够知道这个类的所有属性和方法,调用方法/访问属性,不需要提前在编译期知道运行的对象是谁,他允许运行中的Java程序获取类的信息,并且可以操作类或对象内部属性。
程序中对象的类型一般都是在编译期就确定下来的,而当我们的程序在运行时,可能需要动态的加载一些类,这些类因为之前用不到,所以没有加载到jvm,这时,使用Java反射机制可以在运行期动态的创建对象并调用其属性,它是在运行时根据需要才加载。
02
用途
只是知道概念还不能更明白反射到底是什么?,那么反射都在哪些用途上使用呢?我们开发中哪些情况下使用?
一般来说反射是用来做框架的,做一些抽象度比较高的底层代码。
反射是框架设计的灵魂。
反射都有哪些用途呢?
1、首先就是反编译,反编译是 .class-->.java
2、通过反射机制访问java对象的属性,方法,构造方法等
3、当我们在使用IDE,比如Ecplise时,当我们输入一个对象或者类,并想调用他的属性和方法是,一按点号,编译器就会自动列出他的属性或者方法,这里就是用到反射。
4、反射最重要的用途就是开发各种通用框架。
03
解剖类
我们知道一个类里一般有构造函数、方法、成员变量(字段/属性)。
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对象表示。
首先要明白一点,我们写的代码是存储在后缀名是 .java的文件里的,但是它会被编译,最终真正去执行的是编译后的 .class文件。
Java是面向对象的语言,一切皆对象,所以java认为 这些编译后的 class文件,这种事物也是一种对象,它也给抽象成了一种类,这个类就是Class,大家可以去AIP里看一下这个类。
大家可以查看api
04
常用类
Java.lang.Class;
Java.lang.reflect.Constructor;
Java.lang.reflect.Field;
Java.lang.reflect.Method;
Java.lang.reflect.Modifier;
05
实例
1,反射类中的方法
添加一个Person类,添加几种参数的方法。
package com.cj.test;import java.util.Date;public class Person { public Person(){ System.out.println("默认的无参构造方法执行了"); } public Person(String name){ System.out.println("姓名:"+name); } public Person(String name,int age){ System.out.println(name+"="+age); } private Person(int age){ System.out.println("年龄:"+age); } public void m1() { System.out.println("m1"); } public void m2(String name) { System.out.println(name); } public String m3(String name,int age) { System.out.println(name+":"+age); return "aaa"; } private void m4(Date d) { System.out.println(d); } public static void m5() { System.out.println("m5"); } public static void m6(String[] strs) { System.out.println(strs.length); } public static void main(String[] args) { System.out.println("main"); }}
下面我们来看一下调用。
package com.cj.test;import java.lang.reflect.Method;import java.util.Date;import org.junit.Test; public class Test1 { @Test//public void m1() public void test1() throws Exception{ Class clazz = Class.forName("com.cj.test.Person"); Person p = (Person)clazz.newInstance(); Method m = clazz.getMethod("m1", null); m.invoke(p, null); } @Test//public void m2(String name) public void test2() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("m2", String.class); m.invoke(p, "程序职场"); } @Test//public String m3(String name,int age) public void test3() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getMethod("m3", String.class,int.class); String returnValue = (String)m.invoke(p, "程序职场",23); System.out.println(returnValue); } @Test//private void m4(Date d) public void test4() throws Exception{ Class clazz = Person.class; Person p = (Person) clazz.newInstance(); Method m = clazz.getDeclaredMethod("m4", Date.class); m.setAccessible(true); m.invoke(p,new Date()); } @Test//public static void m5() public void test5() throws Exception{ Class clazz = Person.class; Method m = clazz.getMethod("m5", null); m.invoke(null,null); } @Test//private static void m6(String[] strs) public void test6() throws Exception{ Class clazz = Person.class; Method m = clazz.getDeclaredMethod("m6",String[].class); m.setAccessible(true); m.invoke(null,(Object)new String[]{"a","b"}); } @Test public void test7() throws Exception{ Class clazz = Person.class; Method m = clazz.getMethod("main",String[].class); m.invoke(null,new Object[]{new String[]{"a","b"}}); }}
2,反射类中的属性字段
package com.cj.test;import java.util.Date;public class Person { public String name="程序职场"; private int age = 18; public static Date time; public int getAge() { return age; } public Person(){ System.out.println("默认的无参构造方法执行了"); } public Person(String name){ System.out.println("姓名:"+name); } public Person(String name,int age){ System.out.println(name+"="+age); } private Person(int age){ System.out.println("年龄:"+age); } public void m1() { System.out.println("m1"); } public void m2(String name) { System.out.println(name); } public String m3(String name,int age) { System.out.println(name+":"+age); return "aaa"; } private void m4(Date d) { System.out.println(d); } public static void m5() { System.out.println("m5"); } public static void m6(String[] strs) { System.out.println(strs.length); } public static void main(String[] args) { System.out.println("main"); }}
结果调用。
package com.cj.test;import java.lang.reflect.Field;import java.util.Date;import org.junit.Test; public class Demo3 { //public String name="李四"; @Test public void test1() throws Exception{ Class clazz = Person.class; Person p = (Person)clazz.newInstance(); Field f = clazz.getField("name"); String s = (String)f.get(p); System.out.println(s); //更改name的值 f.set(p, "王六"); System.out.println(p.name); } @Test//private int age = 18; public void test2() throws Exception{ Class clazz = Person.class; Person p = (Person)clazz.newInstance(); Field f = clazz.getDeclaredField("age"); f.setAccessible(true); int age = (Integer)f.get(p); System.out.println(age); f.set(p, 28); age = (Integer)f.get(p); System.out.println(age); } @Test//public static Date time; public void test3() throws Exception{ Class clazz = Person.class; Field f = clazz.getField("time"); f.set(null, new Date()); System.out.println(Person.time); }}
3,反射方法的其他使用--通过反射越过泛型检查
import java.lang.reflect.Method;import java.util.ArrayList;/* * 通过反射越过泛型检查 * 例如:有一个String泛型的集合,怎样能向这个集合中添加一个Integer类型的值? */public class Demo { public static void main(String[] args) throws Exception{ ArrayList<String> strList = new ArrayList<>(); strList.add("aaa"); strList.add("bbb"); // strList.add(100); //获取ArrayList的Class对象,反向的调用add()方法,添加数据 Class listClass = strList.getClass(); //得到 strList 对象的字节码 对象 //获取add()方法 Method m = listClass.getMethod("add", Object.class); //调用add()方法 m.invoke(strList, 100); //遍历集合 for(Object obj : strList){ System.out.println(obj); } }}
讲了这么多,赶紧试试吧,在项目使用中更方便。
祝看完这篇文章的小伙伴收获满满!
标签:Java,String,System,不看,Person,这篇,println,public,out 来源: https://blog.51cto.com/u_14365196/2989039