一、
1.核心操作:Object
public final native Class<?> getClass(); :返回Class类
Class:反射核心类,描述其他类的类结构
2.Class类的三种实例化方式(每个类的Class对象有且只有一个,由JVM在类加载时创建)
a.任意对象.getClass()
b.类名.class
c.调用Class的静态方法Class.forName(String className)
3.利用class对象反射创建具体类的实例化对象
Class类中提供如下方法:
public T newInstance(){
throws InstantiationException,Illeg
}
二、反射与类操作
取得类的包名称:cls.getPackage()
取得父类的Class对象:cls.getSuperclass()
取得父类名称:cls.getSuperclass().getName()
取得实现的父接口对象:cls.getInterface
package reflectexcrise.reflect;
interface Ifruit{}
interface IMessage{}
class Cls implements Ifruit,IMessage{}
public class test {
public static void main(String[] args) {
Class<?> cls=Cls.class;
//取得包名称
System.out.println(cls.getPackage().getName());
//取得父类名称
System.out.println(cls.getSuperclass().getName());
//取得实现的父接口对象
Class<?>[] iClass=cls.getInterfaces();
for(Class<?> iclass1 :iClass ) {
System.out.println(iclass1.getName());
}
}
}
反射调用构造:
反射调用构造方法
I Class提供的newInstance()默认调用类中的无参构造
II Class提供的getConstructor(参数---)取得类中构造方法
III 取得类中所有构造方法。
pulbic Constructors<?>[] getConstructors
II和III只能取得所有修饰符为public的构造方法
取得类中所有构造方法,与修饰符无关:
getDeclaredConstructor
getDeclaredConstructors
package reflectexcrise.reflect;
import java.lang.reflect.Constructor;
class Person{
public Person(){}
public Person(String name) {}
public Person(String name,int age) {}
}
public class test {
public static void main(String[] args) {
Class<?> cls=Person.class;
//取得类中全部构造
Constructor<?>[] constructors=cls.getConstructors();
for(Constructor<?> constructor : constructors) {
System.out.println(constructor);
}
}
}
打印时的操作:直接利用了constructor类中的toString()方法取得了构造方法的完整信息(包含方法权限,参数列表),而如果你只使用了getName()方法,只会返回构造方法的包名.类名。
class类通过反射实例化对象的时候,只能调用类中的无参构造。如果现在类中没有无参构造则无法使用class类调用,只能够通过明确的构造调用实例化处理。
package reflectexcrise.reflect;
class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
Class<?> cls=Person.class;
System.out.println(cls.newInstance());
}
}
上面的代码需要加上一个空实现的无参构造。写简单java类要加上无参构造。
例:通过constructor类实例化对象
调用newInstance方法取得具体类的实例化对象。
package reflectexcrise.reflect;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
class Person{
private String name;
private int age;
public Person(String name, int age) {
super();
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
}
public class test {
public static void main(String[] args) throws NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, InstantiationException, IllegalAccessException {
Class<?> cls=Person.class;
Constructor<?> cons=cls.getConstructor(String.class,int.class);
System.out.println(cons.newInstance("lyz",21));
}
}
3.反射调用普通方法(核心)
1.取得所有普通方法:
取得本类及父类所有普通方法 权限为public: getMethods()
取得本类所有普通方法 权限无关: getDeclaredMethods()
2.指定普通方法:
取得本类及父类指定普通方法 权限为public : getMethod(String name,Class<?>)
取得本类指定普通方法 权限无关: getDeclaredMethod(String name)
调用:invoke(Object obj)
取得指定普通方法:
package reflectexcrise.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Person{
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
super();
this.name = name;
this.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;
}
}
public class test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
//取得class对象
Class<?> cls=Person.class;
//取得具体的实例化对象
Person person=(Person)cls.newInstance();
//取得指定方法
Method setMethod=cls.getMethod("setName", String.class);
//通过Method对象调用指定的方法,同时传入参数
setMethod.invoke(person, "lyz");
Method getMethod=cls.getMethod("getName");
Object result=getMethod.invoke(person);
System.out.println(result);
}
}
取得全部普通方法:
getMethods()
package reflectexcrise.reflect;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
class Person{
private String name;
private int age;
public Person() {}
public Person(String name, int age) {
super();
this.name = name;
this.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;
}
}
public class test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException{
//取得class对象
Class<?> cls=Person.class;
Method[] methods=cls.getMethods();
for(Method method : methods) {
System.out.println(method);
}
}
}
4.反射调用类中属性
前提:类中的所有属性一定在类对象实例化之后才会进行空间分配,所以此时如果向调用类的属性必须保证有实例化对象。通过反射的newInstance()可以直接取得实例化对象(Object类型)
在Class类中有两组取得属性的方法:
第一组:
取得父类全部属性:getFields()
取得本类全部属性:getDeclareFields()
第二组:
取得父类指定属性:getField(String name);
取得本类指定属性: getDeclareField(String name);
范例:取得类中全部属性:
package reflectexcrise.reflect;
import java.lang.reflect.Field;
class Person{
public String name;
public int age;
}
class Student extends Person{
private String school;
}
public class test {
public static void main(String[] args) {
Class<?> cls=Student.class;
{
Field[] field=cls.getFields();
for(Field field2 : field) {
System.out.println(field2);
}
}
System.out.println("------------------------------------");
{
Field[] fields=cls.getDeclaredFields();
for(Field field:fields) {
System.out.println(field);
}
}
}
}
属性调用:
Field类提供得方法:
设置属性内容: public void set(具体的实例化对象,属性值)
取得属性内容: public Object get(具体的实例化对象)
动态设置封装:
AccessibleObject: 描述类中结构的可访问性
动态设置封装性:
public void setAccessible(boolean flag) throws securityException
package reflectexcrise.reflect;
import java.lang.reflect.Field;
class Person{
private String name;
}
public class test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
Class<?> cls=Person.class;
Object obj=cls.newInstance();
Field field=cls.getDeclaredField("name");
field.setAccessible(true);
field.set(obj, "lyz");
//相当于对象.name="lyz"
System.out.println(field.get(obj));
}
}
取得属性类型:
package reflectexcrise.reflect;
import java.lang.reflect.Field;
class Person{
private String name;
}
public class test {
public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException, SecurityException {
Class<?> cls=Person.class;
Object obj=cls.newInstance();
Field field=cls.getDeclaredField("name");
System.out.println(field.getType().getName());
System.out.println(field.getType().getSimpleName());
}
}