反射的概念:主要是指程序可以访问,检测和修改它本身状态或行为的一种能力,并能根据自身行为的状态和结果,调整或修改应用所描述行为的状态和相关的语义。
1、Java反射的概念反射含义:可以获取正在运行的Java对象。然后对其1.属性进行访问、赋值、修改。2.调用方法(无参构造方法、带参构造、及其他方法)
2、Java反射的功能
1)可以判断运行时对象所属的类
2)可以判断运行时对象所具有的成员变量和方法
3)通过反射甚至可以调用到private的方法
4)生成动态代理
3、实现Java反射的类
1)Class:它表示正在运行的Java应用程序中的类和接口
2)Field:提供有关类或接口的属性信息,以及对它的动态访问权限
3)Constructor:提供关于类的单个构造方法的信息以及对它的访问权限
4)Method:提供关于类或接口中某个方法信息
反射类:
package com.siebre;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Arrays;
import com.siebre.Student;
/**
* java 程序是先编译后才能运行(加载).
* 反射特点:使用在编译期并不知道的类.
* 反射定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法.
* 对于任意一个对象,都能够调用它的任意一个方法和属性.
* 这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制.
*
* 反射作用:1.进行反编译 class转化成 .java.
* 2.通过反射机制访问类的属性、方法、构造方法.
* 优点:使代码更加灵活.
* 缺点:使软件的性能降低,复杂度增加.
* @author Dason_yu
*
*/
public class Reflection {
public static void main(String[] args) throws Exception {
//1.根据类的全路径进行类加载
Class<?> c = Class.forName("com.siebre.Student");//绝对路径
System.out.println(c);//class com.siebre.Student
System.out.println(c.getName());//com.siebre.Student
System.out.println(2);
//2.获得该类方法 getter/setter/显示出来的方法 除构造方法
Method[] methods = c.getDeclaredMethods();
for(Method method:methods){
System.out.println("类方法:"+method);
}
System.out.println(3);
//3.获得全部方法 还是没有构造方法 但比2获得的方法多 如 wait()
Method[] ms = c.getMethods();
for(Method method:ms){
System.out.println("全部方法:"+method);
}
System.out.println(4);
//4.获取构造方法 无参和带参
Constructor<?>[] cons = c.getConstructors();
//System.out.println(Arrays.toString(cons));
for(Constructor<?> con :cons){
System.out.println("构造方法:"+con);
}
System.out.println(5);
//5.创建对象 调用的是无参构造
Student s = (Student) c.newInstance();
System.out.println("创建对象:"+s);//Student
System.out.println(6);
//6.获得该类的所有属性
//getDeclaredFields():所有属性,私有和公有
//getFields():公有属性
Field[] fs = c.getDeclaredFields();
System.out.println("属性数组:"+Arrays.toString(fs));//所有属性
Field[] fs1 = c.getFields();
System.out.println("属性数组:"+Arrays.toString(fs1));//[public com.siebre.School com.siebre.Student.school]
System.out.println(7);
//7.获取属性的值和修改属性的值 :set()
s.setName("dason");
s.setId(22);
//Class cla = s.getClass();//两个都可以
Class<? extends Student> cla = s.getClass();
//getField()获得某个类的的公共(public)的字段
//Field f1 = cla.getField("name");//报异常
// System.out.println(f1);
Field f2 = cla.getDeclaredField("id");
System.out.println("获取指定属性名:"+f2);//private int com.siebre.Student.id
//私有属性 需要通过 setAccessible() 设置是否访问和修改私有属性
f2.setAccessible(true);
int id = (int) f2.get(s);//访问 s的f2的值
System.out.println("修改前id值:"+id);
f2.set(s, 23);//修改
System.out.println("修改后id值:"+f2.get(s));
System.out.println(8);
//8.调用方法getter setter
//调用setter()方法进行赋值
Method setname = c.getMethod("setName", String.class);
setname.invoke(s, "Dason.yu");//invoke :调用的意思
System.out.println("调用setter方法:"+s.getName());
//调用getter()方法
Method getName = c.getMethod("getName");
System.out.println("调用getter方法:"+getName.invoke(s));
//第二种方式
/*PropertyDescriptor类
PropertyDescriptor类表示JavaBean类通过存储器导出属性.主要方法:
1、getPropertyType();获得属性的Class对象.
2、getReadMethod(),获得用于读取属性值的方法; --> 对应getter
getWriteMethod(),获得用于写入属性值的方法. --> 对应setter
3、hashCode(),获取对象的哈希值.
4、setReadMethod(Method readMethod),设置用于读取属性值的方法;
setWriteMethod(MethodwriteMethod),设置用于写入属性值的方法;
*/
for(int i=0;i<fs.length;i++){
//Field field = fs[i];
PropertyDescriptor pd = new PropertyDescriptor(fs[i].getName(),c);
//System.out.println("pd:"+pd);
//结果:
//pd:java.beans.PropertyDescriptor[name=name; propertyType=class java.lang.String;
//readMethod=public java.lang.String com.siebre.Student.getName();
//writeMethod=public void com.siebre.Student.setName(java.lang.String)]
Method getMethod = pd.getReadMethod();
System.out.println("调用getReadMethod方法:"+getMethod.invoke(s));
}
System.out.println(9);
//9.调用方法 invoke进行执行
//调用eat()方法
Method eat = c.getMethod("eat");
System.out.println("调用eat方法:"+eat.invoke(s));
//调用length(String str)方法
Method lengthMethod1 = c.getMethod("length",String.class);
int k = (int) lengthMethod1.invoke(s, "hello");
System.out.println("调用length方法:"+k);
//第二种方式
Method lengthMethod = c.getMethod("length", new Class[]{String.class});
int i = (int) lengthMethod.invoke(s, new Object[]{"hello"});
System.out.println("调用length方法2:"+i);
//调用静态方法
Method study = c.getMethod("study");
String strings = (String) study.invoke(null);//参数为null 代表不需要创建对象
System.out.println("调用静态方法study:"+strings);//null void没有返回值
Method music = c.getMethod("music",String.class);
System.out.println("调用静态方法music:"+music.invoke(null,"白玫瑰"));
//获得父类:c.getSuperclass();
//获得实现的接口:c.getInterfaces();
}
}
Student类 :
package com.siebre;
import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;
public class Student {
private String name;
private int id;
private String[] array;
private List<String> list;
private Map<String,String> map;
public School school;//school未放上来 注意:其是public修饰 用于测试getFields()
private Date date;
public Student() {
}
public Student(String name, int id, String[] array, List<String> list,
Map<String, String> map, School school,Date date) {
super();
this.name = name;
this.id = id;
this.array = array;
this.list = list;
this.map = map;
this.school = school;
this.date = date;
}
//静态方法
public static void study(){
System.out.println("我正在学习");
}
public static String music(String str){
return str;
}
//无参
public String eat(){
String str = "I like eat meat";
return str;
}
//带参
public int length(String str){
int i = str.length();
return i;
}
//get 和set 方法
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String[] getArray() {
return array;
}
public void setArray(String[] array) {
this.array = array;
}
public List<String> getList() {
return list;
}
public void setList(List<String> list) {
this.list = list;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
public School getSchool() {
return school;
}
public void setSchool(School school) {
this.school = school;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
@Override
public String toString() {
return "Student [name=" + name + ", id=" + id + ", array="
+ Arrays.toString(array) + ", list=" + list + ", map="
+ map + ", school=" + school + ", date=" + date + "]";
}
}
输出结果:
class com.siebre.Student
com.siebre.Student
2
类方法:public void com.siebre.Student.setArray(java.lang.String[])
类方法:public java.lang.String com.siebre.Student.toString()
类方法:public java.lang.String com.siebre.Student.getName()
类方法:public int com.siebre.Student.length(java.lang.String)
类方法:public java.lang.String[] com.siebre.Student.getArray()
类方法:public int com.siebre.Student.getId()
类方法:public void com.siebre.Student.setName(java.lang.String)
类方法:public java.util.Map com.siebre.Student.getMap()
类方法:public java.util.Date com.siebre.Student.getDate()
类方法:public java.lang.String com.siebre.Student.eat()
类方法:public static void com.siebre.Student.study()
类方法:public static java.lang.String com.siebre.Student.music(java.lang.String)
类方法:public void com.siebre.Student.setId(int)
类方法:public void com.siebre.Student.setDate(java.util.Date)
类方法:public java.util.List com.siebre.Student.getList()
类方法:public void com.siebre.Student.setList(java.util.List)
类方法:public void com.siebre.Student.setMap(java.util.Map)
类方法:public com.siebre.School com.siebre.Student.getSchool()
类方法:public void com.siebre.Student.setSchool(com.siebre.School)
3
全部方法:public void com.siebre.Student.setArray(java.lang.String[])
全部方法:public java.lang.String com.siebre.Student.toString()
全部方法:public java.lang.String com.siebre.Student.getName()
全部方法:public int com.siebre.Student.length(java.lang.String)
全部方法:public java.lang.String[] com.siebre.Student.getArray()
全部方法:public int com.siebre.Student.getId()
全部方法:public void com.siebre.Student.setName(java.lang.String)
全部方法:public java.util.Map com.siebre.Student.getMap()
全部方法:public java.util.Date com.siebre.Student.getDate()
全部方法:public java.lang.String com.siebre.Student.eat()
全部方法:public static void com.siebre.Student.study()
全部方法:public static java.lang.String com.siebre.Student.music(java.lang.String)
全部方法:public void com.siebre.Student.setId(int)
全部方法:public void com.siebre.Student.setDate(java.util.Date)
全部方法:public java.util.List com.siebre.Student.getList()
全部方法:public void com.siebre.Student.setList(java.util.List)
全部方法:public void com.siebre.Student.setMap(java.util.Map)
全部方法:public com.siebre.School com.siebre.Student.getSchool()
全部方法:public void com.siebre.Student.setSchool(com.siebre.School)
全部方法:public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
全部方法:public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
全部方法:public final void java.lang.Object.wait() throws java.lang.InterruptedException
全部方法:public boolean java.lang.Object.equals(java.lang.Object)
全部方法: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()
4
构造方法:public com.siebre.Student()
构造方法:public com.siebre.Student(java.lang.String,int,java.lang.String[],java.util.List,java.util.Map,com.siebre.School,java.util.Date)
5
创建对象:Student [name=null, id=0, array=null, list=null, map=null, school=null, date=null]
6
属性数组:[private java.lang.String com.siebre.Student.name, private int com.siebre.Student.id,
private java.lang.String[] com.siebre.Student.array, private java.util.List com.siebre.Student.list,
private java.util.Map com.siebre.Student.map, public com.siebre.School com.siebre.Student.school,
private java.util.Date com.siebre.Student.date]
属性数组:[public com.siebre.School com.siebre.Student.school]
7
获取指定属性名:private int com.siebre.Student.id
修改前id值:22
修改后id值:23
8
调用setter方法:Dason.yu
调用getter方法:Dason.yu
调用getReadMethod方法:Dason.yu
调用getReadMethod方法:23
调用getReadMethod方法:null
调用getReadMethod方法:null
调用getReadMethod方法:null
调用getReadMethod方法:null
调用getReadMethod方法:null
9
调用eat方法:I like eat meat
调用length方法:5
调用length方法2:5
我正在学习
调用静态方法study:null
调用静态方法music:白玫瑰