- java是一个纯面向对象语言,反射也是一个自醒,获取类的信息
- 反射指的是对象的反向处理操作,在正常情况下我们是通过包名.类名找到类,而“反”则是通过Object的方法
public final native Class<?> getClass();
返回一个Class类对象,在反射中看中的不是一个对象,而是对象身后的组成(类、构造、方法、成员)
//反向操作
Date date1 =new Date();
Class cla= date1.getClass();
System.out.println(cla);
//calss.java.util.Date
- 取得父类的属性
在Class类中提供有两组取得属性的方法:
- 第一组(父类中)-取得类中全部属性: public Field[] getFields() throws SecurityException
- 第一组(父类中)-取得类中指定名称属性: public Field getField(String name) throws
NoSuchFieldException, SecurityException - 第二组(本类中)-取得类中全部属性: public Field[] getDeclaredFields() throws SecurityException
- 第二组( 本类中)-取得类中指定名称属性 : public Method getDeclaredMethod(String name, Class<?>… parameterTypes) throws NoSuchMethodException, SecurityException
public class Attribute {
public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, NoSuchMethodException {
Class<?> m = Class.forName("com.bittech.Student");
//取得父类中全部属性
Field[] files = m.getFields();
for (Field filed : files) {
System.out.println(filed);
}
System.out.println("---");
//取得父类中的指定属性
Field files2 = m.getField("school");
System.out.println(files2);
System.out.println("---");
//取得本类中的全部属性
Field[] files3 = m.getDeclaredFields();
for (Field f : files3) {
System.out.println(f);
}
System.out.println("---");
Object obj = m.newInstance();
Field fi = m.getDeclaredField("school");//null
fi.set(obj,"ii");//相当于school="ii"
//取得属性
System.out.println(fi.get(obj));
}
}
class Teacher {
public int age;
public String name;
}
class Student extends Teacher {
public String school;
}
- 反射取得包名称、父类名称、全部构造方法等
Class类通过反射实例化类对象的时候,只能够调用类中的无参构造。如果现在类中没有无参构造则无法使用Class类调用,只能够通过明确的构造调用实例化处理。
interface IFruit1{}
interface IMessage{}
class CLS implements IFruit1,IMessage{}
class Person{
public Person(){}
public Person(String name){}
public Person(String name,int age){}
}
public class SuperClass {
public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
Class<?> cls=CLS.class;
//取得包名称
System.out.println(cls.getPackage().getName());
//取得父类的名称
System.out.println(cls.getSuperclass().getName());
//取得实现的父接口对象
Class<?>[] iClass=cls.getInterfaces();
for(Class<?> class1:iClass){
System.out.println(class1.getName());
}
System.out.println("---");
//取得类中的全部构造
Class<?> cls1=Person.class;
Constructor<?>[] constructors=cls1.getConstructors();
for(Constructor<?> constructor :constructors){
//只返回包名和类名
System.out.println(constructor.getName());
//返回构造方法的全部信息
System.out.println(constructor);
}
System.out.println("----");
//取得指定参数类型的构造方法对象
Constructor<?> cons=cls1.getConstructor(String.class,int.class);
System.out.println(cons.newInstance("yu",23));
}
}
- 反射调用普通方法
- 取得全部普通方法: public Method[] getMethods() throws SecurityException
- 取得指定普通方法: public Method getMethod(String name, Class<?>… parameterTypes)
- 以上两个方法泛型的类型是java.lang.reflect.Method类的对象,在此类中提供有一个调用方法的支持:public Object invoke(Object obj, Object… args)throws IllegalAccessException, IllegalArgumentException,InvocationTargetException
public class Reflection {
public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, ClassNotFoundException, InvocationTargetException {
// Class<?> cls3 = Person1.class;
//1.所有的普通方法必须在有实例化对象之后才可以进行调用
//取得一个类中全部普通方法
// Method[] method = cls3.getMethods();
// for (Method m : method) {
// System.out.println(m);
// }
Class<?> cls4 = Class.forName("com.bittech.Person1");
Object obj = cls4.newInstance();
// 取得setName这个方法的实例化对象,设置方法名称与参数类型
Method setMethod = cls4.getMethod("setName", String.class);
// 随后需要通过Method类对象调用指定的方法,调用方法需要有实例化对象
// 同时传入参数
setMethod.invoke(obj, "yu"); // 相当于Person对象.setName("yuisama") ;
Method getMethod = cls4.getMethod("getName");
Object result1 = getMethod.invoke(obj); // 相当于Person对象.getName() ;
System.out.println(result1);
}
}
class Person1 {
private String name;
private int age;
public Person1() {
}
public Person1(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
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;
}
}
- 反射封装
在AccessibleObject类中提供有一个方法:动态设置封装:public void setAccessible(boolean flag) throws SecurityException
* 1. 设置属性内容 : public void set(Object obj, Object value) throws IllegalArgumentException, IllegalAccessException
* 2. 取得属性内容 : public Object get(Object obj) throws IllegalArgumentException, IllegalAccessException
* 3.取得属性类型 :public Class<?> getType()
*/
public class Encapsulate {
public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchFieldException {
Class<?> cls5 = Class.forName("com.bittech.Friend1");
//实例化本类对象
Object obj = cls5.newInstance();
//操作name属性
Field field0 = cls5.getDeclaredField("name");
//设置属性内容,等价于对象.name="ii",设置封装,运行的时候会出错
//field0.set(obj, "ii");
//取消封装
field0.setAccessible(true);
field0.set(obj, "i");
//取得属性内容
System.out.println(field0.get(obj));
//包.类
System.out.println(field0.getType().getName());
//类名称
System.out.println(field0.getType().getSimpleName());
}
}
class Friend1 {
private String name;
}
i
java.lang.String
String
获取包、继承得类,只返回一个类单继承