Java 反射
简介
JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。
当JVM把class加载到内存的时候,会同步的产生关于这个文件的Class对象,这个对象里面封装的就是类的信息,而且,不管我们new 使用多少次,我们的JVM只会为它创建一个Class对象。
我们反射的本质就是得到Class对象之后,通过调用Class中的方法反向的获取Person对象的各种信息
获取Class对象
反射的关键是要获取到对象,然后调用Class对象里面的信息来达到我们的目的,比如类的路径,方法,变量等等,下面介绍下获取Class对象的几种方式
第一种
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) {
Demo demo=new Demo();
Class demoClass = demo.getClass();
System.out.println("get class first info"+demoClass);
}
比如传递过来Object,可通过该方式获取对象
第二种
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) {
Class demoClass = Demo.class;
System.out.println("get class second info"+demoClass);
}
程序性能更高,安全可靠
第三种
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) {
try{
Class demoClass = Class.forName("com.glj.webservice.demo.Demo");
System.out.println("获取到的对象:" + demoClass);
} catch (Exception e){
e.printStackTrace();
}
}
forName() 静态方法来获取,用的最多
反射-获取成员变量
package com.glj.webservice.demo.reflex;
import java.io.Serializable;
public class ReflexClass implements Serializable {
public String name;
private int age;
String address;
protected String count;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
@Override
public String toString() {
return "ReflexClass{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", count='" + count + '\'' +
'}';
}
}
package com.glj.webservice.demo.reflex;
import java.lang.reflect.Field;
import java.util.Arrays;
public class ReflexTest {
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) throws Exception {
// 获取Class 对象 可通过上述三种方式任何一种即可
Class perClass = ReflexClass.class;
System.out.println("获取所有字段");
Field[] fields = perClass.getDeclaredFields();
Arrays.stream(fields).forEach(v -> System.out.println(v));
System.out.println("获取所有的public 字段");
fields = perClass.getFields();
Arrays.stream(fields).forEach(v -> System.out.println(v));
System.out.println("根据名字获取指定字段");
Field f = perClass.getDeclaredField("address");
System.out.println(f);
// 将Class 对象进行初始化
Object ob = perClass.getConstructor().newInstance();
f.set(ob,"北京市朝阳区望京Soho 塔1");
ReflexClass re = (ReflexClass)ob;
System.out.println("获取设定的值"+re.getAddress());
}
}
打印结果:
获取所有字段
public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
private int com.glj.webservice.demo.reflex.ReflexClass.age
java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
protected java.lang.String com.glj.webservice.demo.reflex.ReflexClass.count
获取所有的public 字段
public java.lang.String com.glj.webservice.demo.reflex.ReflexClass.name
根据名字获取指定字段
java.lang.String com.glj.webservice.demo.reflex.ReflexClass.address
获取设定的值北京市朝阳区望京Soho 塔1
反射-获取构造函数并调用
package com.glj.webservice.demo.reflex;
import java.io.Serializable;
public class ReflexClass implements Serializable {
/**
* public
*/
public String name;
/**
* 默认
*/
String address;
/**
* 受保护的
*/
protected String count;
/**
* 私有的
*/
private int age;
/**
* 无参构造
*/
public ReflexClass() {
System.out.println("调用了公有、无参构造方法");
}
/**
* public 字段构造
* @param name
*/
public ReflexClass(String name) {
this.name = name;
System.out.println("公共字段一个参数构造 name:" + name);
}
/**
* 多个字段构造
* @param name
* @param address
*/
public ReflexClass(String name, String address) {
this.name = name;
this.address = address;
System.out.println("name:"+name+"address:"+ address);
}
/**
* protected 构造
* @param age
*/
protected ReflexClass(int age) {
this.age = age;
System.out.println("受保护的构造方法age = " + age);
}
/**
* 私有的构造
* @param bls
*/
private ReflexClass(boolean bls) {
System.out.println("受保护的构造方法bls = " + bls);
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getCount() {
return count;
}
public void setCount(String count) {
this.count = count;
}
@Override
public String toString() {
return "ReflexClass{" +
"name='" + name + '\'' +
", age=" + age +
", address='" + address + '\'' +
", count='" + count + '\'' +
'}';
}
}
package com.glj.webservice.demo.reflex;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.Arrays;
public class ReflexTest {
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) throws Exception {
Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");
System.out.println("获取所有的公有构造");
Constructor[] constructors = demoClass.getConstructors();
Arrays.stream(constructors).forEach(v -> System.out.println(v));
System.out.println("所有的构造方法(包括:私有、受保护、默认、公有)");
constructors = demoClass.getDeclaredConstructors();
Arrays.stream(constructors).forEach(v -> System.out.println(v));
System.out.println("获取公有的无参构造");
Constructor constructor = demoClass.getConstructor();
System.out.println(constructor);
System.out.println("根据类型获取构造");
constructor = demoClass.getDeclaredConstructor(boolean.class);
System.out.println(constructor);
// 暴力访问(忽略掉修饰符)
constructor.setAccessible(true);
constructor.newInstance(Boolean.FALSE);
}
}
输出结果
获取所有的公有构造
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass()
所有的构造方法(包括:私有、受保护、默认、公有)
private com.glj.webservice.demo.reflex.ReflexClass(boolean)
protected com.glj.webservice.demo.reflex.ReflexClass(int)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String,java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass(java.lang.String)
public com.glj.webservice.demo.reflex.ReflexClass()
获取公有的无参构造
public com.glj.webservice.demo.reflex.ReflexClass()
根据类型获取构造
private com.glj.webservice.demo.reflex.ReflexClass(boolean)
私有构造方法bls = false
反射-获取方法并调用
package com.glj.webservice.demo.reflex;
import java.io.Serializable;
public class ReflexClass implements Serializable {
public void getName(){
System.out.println("调用了共有的无参方法getName");
}
private void getName(String name){
System.out.println("调用了共有的无参方法getName:"+name);
}
protected void getAge(int age){
System.out.println("调用了共有的无参方法getAge:"+age);
}
void run(){
System.out.println("调用了:默认的,无参的run()");
}
private String study(int age){
System.out.println("调用了,私有的,并且有返回值的,int参数的study(): age = " + age);
return "abcd";
}
public String getAll(int age,String name){
System.out.println("调用了公共的并且有返回值的age"+age+"name"+name);
return "age"+age+"name"+name;
}
}
package com.glj.webservice.demo.reflex;
import java.lang.reflect.Method;
import java.util.Arrays;
public class ReflexTest {
/**
* 获取Class对象
* @param args
*/
public static void main(String[] args) throws Exception {
Class demoClass = Class.forName("com.glj.webservice.demo.reflex.ReflexClass");
System.out.println("获取所有的方法(私有、公有、受保护、默认)");
Method[] methods = demoClass.getDeclaredMethods();
Arrays.stream(methods).forEach(v -> System.out.println(v));
System.out.println("获取所有公有的方法");
methods = demoClass.getMethods();
Arrays.stream(methods).forEach(v -> System.out.println(v));
System.out.println("根据方法名称获取的方法有参");
Method method = demoClass.getDeclaredMethod("getName",String.class);
System.out.println(method);
Object ob = demoClass.getConstructor().newInstance();
method.setAccessible(true);
// 两个参数 一个是参数值 一个是参数类型
method.invoke(ob,"刘德华");
}
}
输出结果
获取所有的方法(私有、公有、受保护、默认)
void com.glj.webservice.demo.reflex.ReflexClass.run()
public void com.glj.webservice.demo.reflex.ReflexClass.getName()
private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
private java.lang.String com.glj.webservice.demo.reflex.ReflexClass.study(int)
protected void com.glj.webservice.demo.reflex.ReflexClass.getAge(int)
获取所有公有的方法
public void com.glj.webservice.demo.reflex.ReflexClass.getName()
public boolean java.lang.Object.equals(java.lang.Object)
public java.lang.String java.lang.Object.toString()
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
根据方法名称获取的方法有参
private void com.glj.webservice.demo.reflex.ReflexClass.getName(java.lang.String)
调用了共有的无参方法getName:刘德华
总结
Java 反射很多,只介绍到常用的获取变量 获取构造获取方法,这几个目前够用了,后续再慢慢补充