反射机制是一个动态机制,它允许我们在程序运行期间再确定实例化,方法的调用,属性的操作等,使得程序的灵活度大大提高,但是随之带来了更多的系统开销和较低的运行效率
因此,反射机制不能被过度使用
使用反射机制的第一步:获取要操作的类的类对象,即:Class的实例JVM中被加载的类都有且只有一个Class的实例与之对应,该实例就称为被加载的这个类的类对象.类对象上会记录这其表示的类的一切信息(类名,方法信息,属性信息等)
获取一个类的类对象方式:
1:类名.class:
Class cls = String.class;
Class cls = int.class;2:Class.forName(String className)
Class cls = Class.forName("java.lang.String")
参数要求是要加载的类的完全限定名:包名+类名3:类加载器ClassLoader形式加载
获取String的类对象
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个类名:");
String className = scanner.nextLine();
通过类对象获取String的一切信息
Class cls = Class.forName(className);
查看类名,java.lang.String
String name = cls.getName();
System.out.println(name);
简单的类名String
name = cls.getSimpleName();
System.out.println(name);
Class称为类对象,其每一个实例用于表示一个类的信息 Method称为方法对象,其每一个实例用于表示一个方法的信息通过Method可以:获取一个方法的所有信息(方法名,参数信息,返回值类型,访问修饰符等)可以通过对象执行这个方法.
Package p =cls.getPackage();
System.out.println("包名:"+p.getName());
获取String的所有方法
Method[] methods = cls.getMethods();
for(Method method : methods){
System.out.println(method.getName());
}
使用反射机制实例化对象
新建一个对象并输出
Person p = new Person();
System.out.println(p);
反射机制实例化对象
1:加载要实例化对象的类的类对象
Class cls = Class.forName("reflect.Person");//加载可以明显的发现虽然内容相同但是地址不同
Scanner scanner = new Scanner(System.in);
System.out.println("请输入一个类名:");
String className = scanner.nextLine();
Class cls = Class.forName(className);
2:利用类对象来实例化
Object obj = cls.newInstance();//利用公开的无参的构造器实例化对象new Person()
System.out.println(obj);
cls.getConstructor();//不传参数时,获取的就是无参构造器
Person p = new Person("李四",22);
System.out.println(p);
Class cls = Class.forName("reflect.Person");
Constructor c = cls.getConstructor(String.class,int.class);//Person(String,int)
Object obj = c.newInstance("王五",33);//new Person("王五",33);
System.out.println(obj);
使用反射机制调用方法
getMethod获取需要的方法
getMethods获取所有的方法
新建对象
Scanner scanner = new Scanner(System.in);
System.out.println("请输入类名:");
String className = scanner.nextLine();
System.out.println("请输入方法名:");
String methodName = scanner.nextLine();
实例化
Class cls = Class.forName(className);
Object obj = cls.newInstance();
获取要调用的方法
Method method = cls.getMethod(methodName);
method.invoke(obj);//p.sayHello();
调用有参方法
*/
public class ReflectDemo5 {
public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException, IllegalAccessException, InstantiationException {
Class cls = Class.forName("reflect.Person");
Object obj = cls.newInstance();
//say(String info)
Method m1 = cls.getMethod("say",String.class);
m1.invoke(obj,"你好");//obj.say("你好");
//say(String info,int count)
Method m2 = cls.getMethod("say",String.class,int.class);
m2.invoke(obj,"呵呵",5);
}
}
调用私有方法
Class的方法:
Method getMethod()
Method[] getMethods()
上述两个方法只能用于获取Class所表示的类的公开方法(包含从超类继承的)
Method getDeclaredMethod()
Method[] getDeclaredMethods()
上述两个方法可以获取Class所表示的类中自己定义的方法包含私有的,不包含从超类继承的
Method method = cls.getDeclaredMethod("heihei");
method.setAccessible(true);//强行打开访问权限
method.invoke(obj);