复习JavaSe----反射
1.概述
反射是根据字节码文件,反射类的信息,字段,方法,构造方法等类的内容,根据字节码文件创造对象,调用方法的技术
反射的基础是Class对象
我们可以用反射将一个类进行剖析,把类的各个信息映射成一个一个的对象
2.用法:
1.每个类都有一个class属性
Class class1=反射.class;//每个类都有一个class属性
2.每个类都有一个getClass方法
Class class2=new 反射().getClass();//每个类都有一个getClass方法
3.通过Class的forName方法
Class class3=Class.forName("这里填类的位置");//通过Class的forName方法
例子一:反射的基础
目标类
public class 我是静态代码块 {
static {
System.out.println("我是静态代码块1");
}
}
反射类
/*
* 反射的基础是class对象
* 如何获取class对象
*/
public class 反射 {
public static void main(String[] args) throws ClassNotFoundException {
Class class1=反射.class;//每个类都有一个class属性
Class class2=new 反射().getClass();//每个类都有一个getClass方法
Class class3=Class.forName("jcc.反射");//通过Class的forName方法
System.out.println(class1);
System.out.println(class1==class2);
System.out.println(class2==class3);
Class class4=int.class;
Class class5=Integer.class;
System.out.println(class4==class5);//false,一个是基本类型,一个是包装类
Class class6=Integer.TYPE;//包装类的TYPE属性返回的是基本类型
System.out.println(class4==class6);//ture
//Class.forName返回Class属性时会把参数指定的类加载到内存
Class class7=我是静态代码块.class;//没有执行静态代码块不输出
Class class8=Class.forName("jcc.我是静态代码块");//执行了静态代码块,说明类加载了内存
}
}
效果:
例子二:反射显示类的修饰符,类名,继承父类,接口
目标类:String
反射类
import java.lang.reflect.Modifier;
public class 反射类的信息 {
public static void main(String[] args) {
Class<?> class1=String.class;
StringBuilder b1=new StringBuilder();//可变字符串,用来存储类的信息
//反射的信息
//修饰符
int mod=class1.getModifiers();
String modigier=Modifier.toString(mod);
b1.append(modigier);
//类名
b1.append(" class ");
// b1.append(class1.getName());//getName返回完整类名--------java.lang.Integer
b1.append(class1.getSimpleName());//返回简易类名
//父类
Class<?> superclass = class1.getSuperclass();
//判断父类是不是Object
if(Object.class!=superclass) {
b1.append(" extends ");
b1.append(superclass.getSimpleName());
}
//接口,可能实现了多个接口,getInterfaces()返回的是数组,如果没有实现接口,返回的数组长度为0
Class<?>[] interfaces = class1.getInterfaces();
if(interfaces.length>0) {
b1.append(" implements ");
//变量数组
for(int i=0;i<interfaces.length;i++)
{
b1.append(interfaces[i].getSimpleName());
//多个实现用,分割
if(i<interfaces.length-1) {
b1.append(",");
}
}
}
System.out.println(b1);
}
}
效果:
例子三:反射访问设置类的属性和方法
目标类
public class Student {
public String name ;
private int age;
public void say() {
System.out.println("name1="+name+",age1="+age);
}
@Override
public String toString() {
return "name="+name+",age="+age;
}
}
反射类:
public class 通过反射访问字段 {
public static void main(String[] args) throws NoSuchFieldException, SecurityException, InstantiationException, IllegalAccessException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
Class<?> class1=Student.class;
Field nameF=class1.getField("name");//反射Student中的name字段,不过为啥叫字段,不叫属性就不知道了
// Field nameF = class1.getDeclaredField("age");
// nameF.setAccessible(true);//将可访问性设为ture,这样私有的也能访问
Object p1=class1.newInstance();//通过反射技术创建实例,默认调用无参
nameF.set(p1, "李白");//设置字段的值,有点像set,get方法,虽然Student类中没有设置
//返回字段的值
System.out.println(p1);
System.out.println(nameF.get(p1));
//反射方法
Method method = class1.getMethod("say",null);//无参写null
method.invoke(p1, null);
}
}
效果:
还有的疑问:
class属性是谁的属性,Object里面没有,百度了一下,答案都不是很清楚,而且答案的差评很多=。=