java反射

1.反射的概念

  • 在运行状态中,对于任意一个类都能够知道这个类所有的属性和方法; 并且对于任意一个对象,都能够调用它的任意一个方法;这种动态获取信息以及动态调用对象方 法的功能成为 Java 语言的反射机制。

2.反射的使用

2.1 获取Class对象

方式一:通过对象的getClass()方法获取 。如果类中有定义静态块则会运行它

public class ReflectTest {
    public static void main(String[] args) {
        ReflectTest reflectTest = new ReflectTest();
        Class clazz = reflectTest.getClass();
        System.out.println(clazz);
    }
}

方式二:通过类的classs属性获取。如果类中有定义静态块则会运行它

public class ReflectTest {
    public static void main(String[] args) {
         Class clazz = ReflectTest.class;
        System.out.println(clazz);
    }
}

方式三:通过Class的forName静态方法,forName有两个重载方法,className参数方法在创建Class对象时默认执行类中定义的静态代码块。另外一个forName方法通过参数控制是否需要运行静态代码块,并指定类加载器。

public class ReflectTest {
    static {
        System.out.println("静态代码块");
    }

    public static void main(String[] args) {
        try {
            //会执行静态代码块
            Class clazz = Class.forName("com.javabase.reflect.ReflectTest");
            System.out.println(clazz);
            //通过false指定不执行静态代码块
            Class clazzFalse =Class.forName("com.javabase.reflect.ReflectTest",false,ClassLoader.getSystemClassLoader());
            System.out.println(clazzFalse);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
}
//这里通过true表明需要执行静态代码块
 @CallerSensitive
    public static Class<?> forName(String className)
                throws ClassNotFoundException {
        Class<?> caller = Reflection.getCallerClass();
        return forName0(className, true, ClassLoader.getClassLoader(caller), caller);
    }

2.2 获取Class对象的方法集合

  1. java.lang.Class#getMethod(String name, Class<?>… parameterTypes):获取指定名称的public方法,包含继承的父类方法。
  2. java.lang.Class#getMethods:获取所有public类型的方法,包括继承类的公共方法
  3. java.lang.Class#getDeclaredMethods:获取类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
public class ReflectTest extends ParentReflect {
    static {
        System.out.println("静态代码块");
    }

    private String name;
    public static final int age = 0;
    public String address;

    private String getName() {
        return name;
    }

    protected void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("com.javabase.reflect.ReflectTest");
            //通过指定方法名获取方法,只能获取public类型的方法,包括继承类的公共方法
            Method methodByName = clazz.getMethod("getParentName");
            System.out.println(methodByName);
            //获取所有public类型的方法,包括继承类的公共方法
            Method[] methods = clazz.getMethods();
            for (Method method : methods) {
                System.out.println(method);
            }
            //获取类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
            Method[] methodAll = clazz.getDeclaredMethods();
            for (Method method : methodAll) {
                System.out.println(method);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (NoSuchMethodException e) {
            e.printStackTrace();
        }
    }
}

2.3 获取构造方法

public class ReflectTest extends ParentReflect {
    static {
        System.out.println("静态代码块");
    }

    public ReflectTest() {
    }

    private ReflectTest(String name, String address) {
        this.name = name;
        this.address = address;
    }

    private String name;
    public static final int age = 0;
    public String address;

    private String getName() {
        return name;
    }

    protected void setName(String name) {
        this.name = name;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public static void main(String[] args) {
        try {
            Class clazz = Class.forName("com.javabase.reflect.ReflectTest");
            //获取当前类的公共构造函数
            Constructor[] constructors = clazz.getConstructors();
            for (Constructor constructor : constructors) {
                System.out.println(constructor);
            }
            //获取指定参数的公共构造函数
            Constructor constructor =clazz.getConstructor();
            System.out.println(constructor);
            //获取类或接口声明的所有构造函数,包括公共、保护、默认(包)访问和私有方法
            Constructor[] constructorAll = clazz.getDeclaredConstructors();
            for (Constructor cons : constructorAll) {
                System.out.println(cons);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }catch (NoSuchMethodException e){
            e.printStackTrace();
        }
    }
}

2.4获取成员变量

  • getFiled:访问公有的成员变量
  • getDeclaredField:所有已声明的成员变量,但不能得到其父类的成员变量

2.5创建对象的两种方法

  • java.lang.Class#newInstance:clazz.newInstance()
  • java.lang.reflect.Constructor#newInstance:constructor.newInstance()

2.6 反射机制的优缺点

  • 优点:可以动态执行,在运行期间根据业务功能动态执行方法、访问属性,最大限度发挥了java的灵活性。
  • 缺点:反射的效率很低,而且会破坏封装,通过反射可以访问类的私有方法,不安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值