1.用来被实例化类
package day13;
public class Person {
private String name;
private int age;
public void sayHello() {
System.out.println("hello!");
}
public void sayName() {
System.out.println("My name is linsa.");
}
private void sayHaha() {
System.out.println("haha!");
}
public void sayInfo(String info) {
System.out.println("这个参数是:"+info);
}
public void sayInfo(String name,int age) {
System.out.println("我叫:"+name+",我今年"+age+"岁。");
}
}
2.获得实例化类的属性跟行为
package day13;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.Scanner;
/**
* java反射机制
* 反射机制允许我们在程序运行期间动态一个类
* 的信息,并实例化。
* 通过反射机制还可以查看某个指定类的信息
* (有哪些方法等),并可以动态调用它们。
* java流行的框架中都用到了反射机制。
*
* 有了反射机制,可以让程序执行代码从
* 编码期确定调用关系转变为在运行期
* 确定。大大提高了代码执行的灵活性。
* @author soft01
*
*/
public class ClassDemo {
public static void main(String[] args) throws ClassNotFoundException {
// Person p = new Person();
// p.sayName();
Scanner scan = new Scanner(System.in);
System.out.println("请输入你想实例化的类:");
String line = scan.nextLine();
//创建类加载器,用于加载需要实例化的类的class
ClassLoader loader = ClassLoader.getSystemClassLoader();
/*
* Class类的每一个实例用于表示JVM加载的一个类的信息
* 每个被JVM加载的类都有且只有一个Class的实例与之对应。
* 通过Class的实例可以获取它表示的相关信息:
* 属性,方法等都可以获取到。
*/
Class c = loader.loadClass(line);
System.out.println(c.getName());
/*
* Class定义的方法:
* String getName()
* 获取当前Class所表示的类的名字
*
* Method[] getMethods()
* 获取当前Class所表示的类的所有方法(自己定义的
* 和从父类继承的)
*
* Method[] getDeclaredMethods()
* 获取当前Class所表示的类自己定义的方法
* 不含有从父类继承下来的。
*/
Method[] methods = c.getDeclaredMethods();
// Method[] methods1 = c.getMethods();
System.out.println(c.getName()+"有"+methods.length);
for(Method method : methods) {
System.out.println(method.getName());
}
/*
* 获取属性信息
*/
Field[] fields = c.getDeclaredFields();
System.out.println(c.getName()+"有"+fields.length);
for(Field field : fields) {
System.out.println(field.getName());
}
}
}
3.获得实例化类指定的方法
package day13;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Scanner;
/**
* 使用反射机制执行指定类的指定方法
* @author soft01
*
*/
public class ClassDemo2 {
public static void main(String[] args) throws ClassNotFoundException,
InstantiationException, IllegalAccessException, NoSuchMethodException,
SecurityException, IllegalArgumentException, InvocationTargetException {
/*
* 执行Person类的sayHello方法
*/
//1:实例化Person
Person p = new Person();
//2:调用p对象的sayHello方法
p.sayHello();
Scanner scan = new Scanner(System.in);
System.out.println("要实例化的类:");
String className = scan.nextLine();
System.out.println("调用"+className+"的哪个方法:");
String methodName = scan.nextLine();
/*
* 反射机制实现
* 1:加载Person类
* 2:实例化该类的实例
* 3:调用相应的方法
*/
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class c = loader.loadClass(className);
/*
* Class提供了创建对应类实例的方法:
* Object new Instance
* 该方法会调用Class所表示的类的无参
* 构造方法来实例化该对象
*/
Object o = c.newInstance();
/*
* Class提供了获取指定名字和对应参数列表方法
* Method getDeclaredMethods(String name,Class[] paras)
* 第一个参数为方法的名字
* 第二个参数是一个Class数组,表示参数列表。若该方法
* 没有参数,那么这个数组可以为null。
*/
Method m = c.getDeclaredMethod(methodName,null);
/*
* Method类的每一个实例用于表示一个类中的一个方法。
* Method的常用方法:
* invoke(Object o,Object[] paras)
* 该方法是用来调用当前Method方法。
* 参数1:调用给定对象o的这个方法。
* 参数2:若Method所表示的该方法有参数,
* 则该数组表示实际需要传入的参数。
* 若该方法没有参数,则传入null即可。
*/
/*
* 若Method表示的是一个私有方法
* 需要开放权限
* 这样会破坏程序设计中的封装性,慎用。
*/
//判断是否为私有方法
if(m.getModifiers()== Modifier.PRIVATE) {
System.out.println(m.getName()+"是一个私有方法!");
m.setAccessible(true);
}
Object returnValue = m.invoke(o, null);
System.out.println("返回值:"+returnValue);
}
}
4.调用一个含有参数的方法
package day13;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* 调用一个含有参数的方法
* @author soft01
*
*/
public class ClassDemo3 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException,
SecurityException, InstantiationException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
ClassLoader loader = ClassLoader.getSystemClassLoader();
Class c = loader.loadClass("day13.Person");
/*
* 获取有参方法:
* 参数1:该方法的名字
* 参数2:这是一个Class类型的数组,数组中的
* 每个元素表示要获取的方法的参数类型。
* 需要注意,这个数组中的元素个数,类型,
* 顺序必须要与要获取的方法的参数列表一致
* 下面方法获取的是Person中的方法:
* sayInfo(String s,int i)
*/
Method m = c.getDeclaredMethod("sayInfo",new Class[] {String.class,int.class});
Object o = c.newInstance();
/*
* 调用invoke时,第二个参数为一个对象数组。
* 数组中的每个元素就是调用这个方法是需要
* 传入的实际参数。
* 下面代码等同调用:
* p.sayInfo("linsa",24)
*/
m.invoke(o, new Object[] {"linsa",24});
}
}