Java反射机制
1.反射机制是什么
反射机制是在运行状态中,对于任何一个类,都能知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取信息以及动态调用对象的方法的功能叫做java的反射机制
2.反射机制能做什么
- 在运行时判断任意一个对象所属的类;
- 在运行时判断任意一个类所具有的成员变量和方法;
- 在运行时构造任意一个类的对象;
- 在运行时调用任意一个对象的方法;
- 生成动态代理
3.反射机制的相关API
- 通过一个对象获得完整的包名和类名
Test test=new Test(); System.out.println(test.getClass().getName);
2.实例化Class类对象
Class<?> class1=null; Class<?> class1=null; Class<?> class1=null; //一般采用这种形式 class1=Class.forName("com.lj.Test"); class2=Test().getClass(); class3=Test.class; System.out.println(“类名称”+class1.getName); System.out.println(“类名称”+class2.getName); System.out.println(“类名称”+class3.getName);
3.获取一个对象的父类与实现的接口
Class<?> clazz=Class.forName("com.lj.Test");
//取得父类
Class<?> parentClass=clazz.getSuperclass();
System.out.println("clazz的父类为:"+parentClass.getName);
//clazz的父类为:java.lang.object
//获取所有实现的接口
Class<?> intes[]=clazz.getInterfaces();
System.out.println("clazz实现的接口有:");
for(int i=0;i<intes.length;i++){
System.out.println((i+1)+":"+intes[i]。getName());
}
4.获取某个类的全部构造函数,通过反射机制实例化一个类的对象
Class<?> class1=null;
class1=Class.forName(com.lj.user);
//第一种方式,实例化默认构造方法,调用set赋值
User user=(User)class1.newInstance();
user.setName("jeck");
user.setAge(20);
System.out.println(user);
//第二种方式,取得全部的构造函数,使用构造函数赋值
Constructor<?> cons[]= class1.getConstructor();
//查看每个构造方法需要的参数
for(int i=0;i<cons.length;i++){
Class<?> clazzs[]=cons[i].getParameterTypes();
System.out.printl("cons["+i+"](");
for(int j=0;j<clazzs.length;j++){
if(j==clazzs.length-1)
System.out.println(clazzs[j].getName);
else
System.out.println(clazzs[j].getName()+",");
}
System.out.println(")")
}
//根据获得的结果选择构造函数实例化类的对象
//cons[0](java.lang.String)
//cons[1](int,java.lang.String)
//cons[2]()
user =(User)cons[0].getInstance("jeck");
System.out.println(user);
user =(User)cons[1].getInstance(20,"jeck");
System.out.println(user);
5.获取某个类的全部属性
Class<?> clazz=Class.forName("com.lj.Test");
System.out.println("---------本类属性---------");
//取得本类的全部属性
Field[] field=clazz.getDeclaredFields();
for(int i=0;i<filed.length;i++){
//权限修饰符
int mo=field[i].getModifiers();
String priv=Modifier.toString(mo);
//属性类型
Class<?> type=field[i].getType();
System.out.println(priv+""+type.getName()+"")+field[i].getName()+";");
}
System.out.println("--------实现的接口或者父类的属性---------")
//取得实现的接口或者父类的属性
Field[] field1=clazz.getFileds();
for(int j=0;j<field1.length;j++){
//权限修饰符
int mo=field[j].getModifiers();
String priv=Modifier.toString(mo);
//属性类型
Class<?> type=field[i].getType();
System.out.println(priv+""+type.getName()+"")+field[j].getName()+";");
}
6.获取某个类的全部方法
Class<?> clazz=Class.forName("com.lj.Test");
Method method[]=clazz.getMethods();//获取类的全部方法
for(int i=0;i,method.length;i++){
Class<?> returnType=method[i].getReturnType();//取得方法的返回类型
Class<?> para[]=method[i].getParameterTypes();
int temp=method[i].getModifiers();//权限修饰符
System.out.print(Modifier.toString(temp)+"");
System.out.print(returnType.getName+"");
System.out.print(method[i].getName+"");
System.out.print("(")
for(int j=0;i,para.length;j++){
System.out.println(para[j].getName()+""+"arg"+j);
if(j<para.length-1){
System.out.println(",");
}
Class<?> exce[]=method[i].getExceptionType[];
if(exce.length>0){
System.out.println(")throws");
for(int k=0;k<exce.length;i++){
System.out.print(exce[k].getName()+"");
if(k<length-1){
System.out.print(",");
}
}
}else{
System.out.print(")");
}
System.out.println();
}
}
7.通过反射机制调用每个类的方法
Class<?> clazz=Class.forName(com.lj.Test);
//调用Test类中的test1方法
Method method=clazz.getMethod("test1");
method.invoke(clazz.newInstance);
//调用Test类的test2方法
method=clazz.getMethod("test2",int.class,String.class);
method.invoke(clazz.newInstance(),20,"jeck");
public void test1(){
System.out.println("java反射机制调用某个类的方法一");
}
public void test2(int age,String name){
System.out.println("java反射机制调用某个类的方法二");
System.out.println("age->"+age+".name->"+name);
}
8.通过反射机制操作某个类的属性
package com.lj;
import java.lang.reflect.field;
public class Test{
private String proprety=null;
public static void main(String[] args)throws Exception{
Class<?> clazz=Class.forName("com.lj.Test");
Object obj=clazz.newInstance();
//可以直接对private的属性赋值
Field field=clazz.getDeclaredField("proprety");
field.setAccessible(true);
field.set(obj,"java反射机制");
System.out.println(field.get(obj));
}
}
9.反射机制的动态代理
// 获取类加载器的方法
TestReflect testReflect = new TestReflect();
System.out.println("类加载器 " + testReflect.getClass().getClassLoader().getClass().getName());
package net.xsoftlab.baike;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
//定义项目接口
interface Subject {
public String say(String name, int age);
}
// 定义真实项目
class RealSubject implements Subject {
public String say(String name, int age) {
return name + " " + age;
}
}
class MyInvocationHandler implements InvocationHandler {
private Object obj = null;
public Object bind(Object obj) {
this.obj = obj;
return Proxy.newProxyInstance(obj.getClass().getClassLoader(), obj.getClass().getInterfaces(), this);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object temp = method.invoke(this.obj, args);
return temp;
}
}
/**
* 在java中有三种类类加载器。
*
* 1)Bootstrap ClassLoader 此加载器采用c++编写,一般开发中很少见。
*
* 2)Extension ClassLoader 用来进行扩展类的加载,一般对应的是jrelibext目录中的类
*
* 3)AppClassLoader 加载classpath指定的类,是最常用的加载器。同时也是java中默认的加载器。
*
* 如果想要完成动态代理,首先需要定义一个InvocationHandler接口的子类,已完成代理的具体操作。
public class TestReflect {
public static void main(String[] args) throws Exception {
MyInvocationHandler demo = new MyInvocationHandler();
Subject sub = (Subject) demo.bind(new RealSubject());
String info = sub.say("Rollen", 20);
System.out.println(info);
}
}
4.反射机制的应用实例
1.在泛型为Interger的ArrayList中存放一个String类型的对象
ArrayList<Interger> list=new ArrayList<Interger>();
Method method=list.getClass().getMethod("add",Object.class);
method.invoke(list,"java反射机制的实例。");
System.out.println(list.get(0));
2.通过反射取得并修改数组的信息
int [] temp={1,2,3,4,5};
Class<?> demo=temp.getClass().getComponentType();
System.out.println("数组类型:"+demo.getName);
System.out.println("数组长度:"+Array.getLength(temp));
System.out.println("数组的第一个元素:"+Array.get(temp,0));
Array.set(temp,0,100);
System.out.println("修改之后的数组的第一个元素为:"+Array.get(temp,0));
3.通过反射机制修改数组的大小
int[] temp={1,2,3,4,5,6,7,8,9};
int[] newTemp=(int[])arrayInc(temp,15);
print(newTemp);
String[] art={"a","b","c"};
String[] atr1=(String[])arrayInc(atr,8);
print(str);
//修改数组大小
public Static Object arrayInc(Object obj,int len){
Class<?> arr=obj.getClass().getComponentType();
Object newArr=Array.newInstance(arr,len);
int co=Array.getLength(obj);
System.arraycopy(obj,0,newArr,0,co);
return newArr
}
//打印
public static void print(Object obj){
Class<?> c=obj.getClass();
if(!c.isArray()){
return;
}
System.out.println("数组长度为:"+Array.getLength(obj));
for(int i=0;i<Array.getLength(obj);i++){
System.out.print(Array.get(obj,i)+"");
}
System.out.println();
}
4.将反射机制应用于工厂模式
package com.lj
interface fruit{
public static void eat();
}
class Apple implements fruit{
public void eat(){
System.out.println("Apple")
}
}
class Orange implements fruit{
public void eat(){
System.out.println("Orange")
}
}
class Factory{
public static fruit getInstance(String ClassName){
fruit f=null;
try{
f=(fruit)Class.forName(ClassName).newInstance();
}catch(Exception e){
e.printStackTrace();
}
return f;
}
}
public class Test{
public static void main(String[] args)throws Exception{
friut f=Factory.getInstance("com.lj.Apple");
if(f!=null){
f.eat();
}
}
}

浙公网安备 33010602011771号