反射
在运行状态中,对于任意一个类,都能够知道这个类的所有的属性方法;
优点:
可以解耦,提高程序的可扩展性。
可以在运行过程中,操作(获取,设置)这些对象。
动态语言:
是一类程序在运行过程中可以改变语言结构的语言。
获取class对象:
1.forName(),将字节码文件加载到内存,返回与带有给定字符串得类或接口相关联的class对象,在源代码阶段,静态获取class对象。
2.类名.class:通过类名属性.class对象获取:class对象阶段
3.对象getclass()返回运行时class类
注意:
同一个字节码文件在加载时只会被加载一次,不会创建多个class对象。
都是同一个对象,加载完类之后就会在堆内存中产生一个clsaa类型的数据,(一个类只有一个对象)。
package com.rongyu.day13;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
/**
* 反射
*/
public class Dome02 {
public static void main(String[] args) throws Exception {
getMethod();
}
//获取属性
public static void getFiled() throws Exception {
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
//获取属性
Field[] declaredFields = aClass.getDeclaredFields();
for (Field declaredField : declaredFields) {
//获取属性的包装类
Class<?> type = declaredField.getType();
String simpleName = type.getSimpleName();
//获取属性名字
String name = declaredField.getName();
//获取属性的修饰符
int modifiers = declaredField.getModifiers();
String s = Modifier.toString(modifiers);
//打印
System.out.println(s+simpleName+name);
}
}
//获取类中的构造方法
public static void getConstructor() throws Exception{
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
//获取类中所有的构造方法
Constructor<?>[] constructors = aClass.getConstructors();
for (Constructor<?> constructor : constructors) {
//获取修饰符
String s = Modifier.toString(constructor.getModifiers());
//获取方法名
String name = constructor.getName();
//获取参数
Class<?>[] parameterTypes = constructor.getParameterTypes();
String str = "";
for (Class<?> parameterType : parameterTypes) {
str += parameterType.getSimpleName()+",";
}
System.out.println(s+name+"("+str+")"+"{}");
}
}
//获取类中的方法
public static void getMethod() throws Exception{
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
Method[] declaredMethods = aClass.getDeclaredMethods();
for (Method declaredMethod : declaredMethods) {
//获取修饰符
String s = Modifier.toString(declaredMethod.getModifiers());
//获取返回值
String simpleName = declaredMethod.getReturnType().getSimpleName();
//获取方法名
String name = declaredMethod.getName();
Class<?>[] parameterTypes = declaredMethod.getParameterTypes();
String str = "";
for (Class<?> parameterType : parameterTypes) {
str += parameterType.getSimpleName()+" ";
}
System.out.println(s+simpleName+name+"("+str+")"+"{}");
}
}
}
package com.rongyu.day13;
import java.lang.reflect.Field;
/**
* 使用反射访问私有的属性,方法
*/
public class Dome03 {
public static void main (String[] args) throws Exception {
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
//实例化class对象
Student o = (Student)aClass.newInstance();
Field name = aClass.getDeclaredField("name");
//值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查
name.setAccessible(true);
//obj - 应该修改其字段的对象
//value - 正被修改的 obj 的字段的新值
name.set(o,"ZhangSan");
System.out.println(o);
}
}
package com.rongyu.day13;
import java.lang.reflect.Array;
/**
* 对数组的反射
*/
public class Dome04 {
public static void main(String[] args) {
Object o = Array.newInstance(String.class, 4);
Array.set(o,0,"1");
Array.set(o,1,"2");
Array.set(o,2,"3");
Array.set(o,3,"4");
for (int i = 0; i < Array.getLength(o); i++) {
Object o2 = Array.get(o, i);
System.out.println(o2);
}
}
}
//反射只有在程序运行的过程中才能会进行赋值
public static void setMethod() throws Exception{
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
//进行实例化对象
Student student = (Student) aClass.newInstance();
Method setName = aClass.getMethod("setName", String.class);
setName.invoke(student, "ZhangSan");
System.out.println(student);
}
package com.rongyu.day13;
import java.lang.reflect.Array;
/**
* 通过反射改变数组的大小
*/
public class Dome05 {
public static void main(String[] args) {
Integer[] arr = {1,2,3,4,5};
//使用反射创建一个新的数组
Object o = Array.newInstance(Integer.class, 10);
//获取原先数组的长度
int length = Array.getLength(arr);
//复制数组
System.arraycopy(arr,0,o,0,length);
//获取数组对象
Class<?> aClass = o.getClass();
//判断该类是不是一个数组
if (!aClass.isArray()){
return;
}
//循环输出数组
for (int i = 0; i < Array.getLength(o); i++) {
Object o1 = Array.get(o, i);
if (o1==null){
break;
}
System.out.println(o1);
}
}
}
//有参的构造方法
public static void getConstructor() throws Exception {
//获取字节码的class对象
Class<?> aClass = Class.forName("com.rongyu.day13.Student");
//得到有参数的构造方法
Constructor<?> constructor = aClass.getConstructor(String.class, Integer.class);
Student zhangSan = (Student)constructor.newInstance("ZhangSan",123);
System.out.println(zhangSan);
}