本文主要内容:
(1)反射概念
(2)如何获取Class
(2)获取Class中常用方法
(4)获取Class中私有属性
(5)操作属性存值、取值
1.反射(reflect)
(1)反射技术是用来描述所有的类,所有的类也有相同的特征,每个类都有属性、方法、构造;每个类都有权限修饰符、特征修饰符
(2)类是用来描述一组对象,反射机制是用来描述一组类
(3)class是用来描述类本身;Field是用来描述类中的属性;Method是用来描述类中的方法;Constructor是用来描述类中的构造方法;Package是用来描述类所属的包;Annotation是用来描述类中的注解(注解可以放在类、属性、方法、构造方法上、参数前面)
2.如何去获取Class(三种)
(1)Class c = Class.forName(“包名.类名”)
(2)Class c = 类名.class;
(3)Class c = 对象的引用.getClass();//Object类中的方法
3.Class中常用方法
(1)int result = getModifiers();获取类的修饰符(权限、特征)
(2)String=getName();//获取名字
(3)String=getSimpleName();//只获取简单名字
(4)Package=getPackage();//获取包名
(5)Class=getSuperClass();//获取超类
(6)Class[]=getInterfaces();//获取所有父接口
(7)Person p=newInstance();//默认调用无参数构造方法创建对象(例如是Person类)
(8)Field[]=getFields();//获取所有属性
(9)Field nameField=getField(“属性名”);//获取属性的相关信息用nameField来调用方法;int=nameField.getModifiers();//获取属性权限修饰符;Class f=nameField.getType();//获取属性的类型(f.getName())
注意:(8)(9)方法只能获取公有的属性,但是包含继承过来的父类属性
public class TestMain {
public static void main(String[] args) {
//通过一个Class对象来操作Person.class类文件
try {
Class clazz = Class.forName("com.refiect.Person");
try {
Person p = (Person) clazz.newInstance();
//相当于调用person类的无参构造方法来创建对象
System.out.println(p);
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
//类有自己的结果、权限修饰符、特征、类名字
int modifiers = clazz.getModifiers();
//将每一个修饰符用一个整数来代替
//0——默认不写;1——public;2——private;4——protected
//8——static;16——final;32——synchronized;等等
System.out.println(modifiers);//1
//获取类的名字
String name = clazz.getName();
String simpleName = clazz.getSimpleName();//只有类名
System.out.println(name);
System.out.println(simpleName);
//获取包名
Package p = clazz.getPackage();
System.out.println(p);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
}
4.操作属性存值、取值(属性公有且已知)
(1)nameField.set(对象,“属性”);//存值
(2)String name=(String)nameField.get(对象);//取值
(3)setAccessable(true);//可以修改属性被操作
5.获取私有属性
(1)Field f=getDeclareField(属性);//获取私有属性;f.setAccessible(true);//表示私有属性可以直接被操作
(2)Field[] f=getDeclareFields();
注意:以上可以获取公有和私有的属性,但是只能获取本类中的属性
6.String类举例
public class TestReflect {
public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException {
String str = new String("abcdefg");
Class c = str.getClass();
Field f = c.getDeclaredField("value");
f.setAccessible(true);
//String类中的value属性用private final修饰,所以数组的地址不能改变
// 只能改变数组中的元素
char[] ch = (char[]) f.get(str);
ch[0] = '小';
ch[1] = '名';
for(int i = 0;i<str.length();i++){
System.out.print(str.charAt(i)+" ");
//小 名 c d e f g
}
}
}