java反射的讲解

java反射的讲解

1.什么是反射?
2,如何获取反射类
3.如果根据反射类获取类对象
4.如何获取类中属性对象
5,如何获取类中方法的对象
6.如何获取类中构造方法对象

1.什么是反射

Java反射是一种强大的机制,它允许程序在运行时动态地检查、访问和修改类、对象、方法和属性等相关信息。通过反射,我们可以在运行时获取类的完整结构,包括成员变量、方法、构造函数等,并且可以动态地调用或修改它们。

.java----通过javac编译---->>(字节码文件)----通过类加载器---->>(.class文件(jvm虚拟机中))

2.如何获取反射类

获取class类对象的三种方式:

第一种:Class.forName("类路径")

第二种:类名.class

第三种:对象.getClass

public class Test01 {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种:根据animal的类路径来获取animal的反射对象
        Class<?> aClass = Class.forName("com.gll.date0810.Test.t1.Animal");
        //第二种: 根据类名来获取animal类的反射对象
        Class<Animal> animalClass = Animal.class;
        //第三种: 通过类对象来获取类的反射类的对象
        Animal animal = new Animal();
        Class<? extends Animal> aClass1 = animal.getClass();
        System.out.println(aClass==animalClass);
        System.out.println(aClass==aClass1);
    }
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Animal{
    private String name;
    private String sex;
}

3.如何根据反射类来获取类对象

通过class类对象,调用 newInstance()来获取类对象

  //第二种: 根据类名来获取animal类的反射对象
        Class<Animal> animalClass = Animal.class;
            //通过反射类来得到对应的类对象,       --之前方式: new animal()来获取animal类的对象
        Animal animal1 = animalClass.newInstance();
        System.out.println(animal1);

4.如何获取反射类中属性成员对象

字节码中的属性成员被加载到内存中后会以Field对象的形式存在。如何获取Field属性对象。

getField(String name) :获取指定属性名的public属性对象

getFields() :获取所有的public 属性对象 包括父类中的属性;

getDeclaredField(String name) :获取指定属性类对象,不能获取包含父类的属性;

getDeclaredFields :获取所有的属性类对象,不包含父类的属性

public class Test02 {
    public static void main(String[] args) throws NoSuchFieldException {
    //1获取stadent类的反射类
        Class<Student> studentClass = Student.class;
        //2获取反射类中的成员对象
        Field[] declaredFields = studentClass.getDeclaredFields();//获取本类中所有的属性对象
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        System.out.println("------------分割线---------------");
        Field[] fields = studentClass.getFields();//获取本类中和父类中public的属性对象
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("----------分割线--------");
        Field field = studentClass.getField("age");//获取指定属性名的public 属性对象
        System.out.println(field);
    }
}
class People{
        public String hand;
        private String foot;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
class Student extends People{
    public String name;
    public int age;
    private int phone;
    String address;
    public void show(){
        System.out.println("正在展示内容,"+name+","+age);
    }
}

4.2 Field类中具有的常用方法

setAccessible(true)  :设置允许访问私有属性
getAnnotation(注解.class)  :获取属性上的注解对象
public class Test03 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchFieldException {
        //1获取反射类对象
        Class<Dog> dogClass = Dog.class;
        //2通过反射类对象来获取类对象
        Dog dog = dogClass.newInstance();
        //得到反射类中的name属性对象
        Field declaredField = dogClass.getDeclaredField("name");
        declaredField.set(dog,"旺财");//通过name属性为Dog对象赋值
        System.out.println(dog);
​
        //得到反射类中的age属性
        Field declaredField1 = dogClass.getDeclaredField("age");
        declaredField1.setAccessible(true); //允许访问私有属性
        declaredField1.set(dog,12);
        System.out.println(dog);
        //获取属性上的注解对象
         My annotation = declaredField.getAnnotation(My.class);
        System.out.println(annotation.value());
    }
}
​
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface My{
    String value();
}
​
@Data
@NoArgsConstructor
@AllArgsConstructor
class Dog{
    @My(value = "名字")
    public String  name;
    private int age;
}
​

5.获取Method方法类对象

getMethod(String name, 类<?>... parameterTypes) 得到指定名称和形参类型的方法 getMethods() :得到所有的public修饰方法。 getDeclaredMethod :根据名字获取本类中的方法 getDeclaredMethods :获取本类所有的方法

public class Test4 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException {
        //1获取反射类
        Class<hello> helloClass = hello.class;
        //2通过反射类来获取类对象
        hello hello = helloClass.newInstance();
​
        //3通过反射类获取本类中所有的方法
        Method[] declaredMethods = helloClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        //4获取本类及父类中public方法
        Method[] methods = helloClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //5获取本类的指定方法
        Method method = helloClass.getDeclaredMethod("h1", int.class);
        System.out.println(method);
​
    }
}
class hi{
    public void h0(){
        System.out.println("what's,up");
    }
}
class hello extends hi{
    public void h1(){
        System.out.println("你好");
    }
    public void h1(int h){
        System.out.println("你好");
    }
    public void h2(){
        System.out.println("我好");
    }
    private void h3(){
        System.out.println("大家好");
    }
​
}

5.2 Method类中常用的方法

invoke:() 执行该方法体

getAnnotation() 获取该注解对象

public class Test4 {
    public static void main(String[] args){
        //1获取反射类
        Class<hello> helloClass = hello.class;
        //2通过反射类来获取类对象
        hello hello = helloClass.newInstance();
​
        //3通过反射类获取本类中所有的方法
        Method[] declaredMethods = helloClass.getDeclaredMethods();
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        //4获取本类及父类中public方法
        Method[] methods = helloClass.getMethods();
        for (Method method : methods) {
            System.out.println(method);
        }
        //5获取本类的指定方法
        Method method = helloClass.getMethod("h1", int.class);
        Object invoke = method.invoke(hello, 888);//回调该方法
        System.out.println("~~~~~~~~~~~~"+invoke);
        //获取注解对象
        My annotation = method.getAnnotation(My.class);
        System.out.println(annotation.value());
​
    }
}
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@interface My{
    String value();
}
class hi{
    public void h0(){
        System.out.println("what's,up");
    }
}
class hello extends hi{
    public void h1(){
        System.out.println("你好");
    }
    @My("dididi")
    public void h1(int h){
        System.out.println("你好1");
    }
​
    public void h2(){
        System.out.println("我好");
    }
    private void h3(){
        System.out.println("大家好");
    }
​
}
​

6.如何获取类中构造方法对象

public Constructor<?>[] getConstructors()返回子类和父类public权限的构造函数的对象数组
public Constructor<?>[] getDeclaredConstructors()获取本类所有构造函数方法,包括所有权限public,private,protected,default权限。
public Constructor getConstructor(Class... parameterTypes)获取单个public权限的构造方法。
public Constructor getDeclaredConstructor(Class... parameterTypes)获取单个构造方法,包括所有权限public,private,protected,default权限。
public class Test5 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Class<Q> qClass = Q.class;
        Q q = qClass.newInstance();
​
•        *//**返回本类中的所有构造
\*        Constructor<?>[] declaredConstructors = qClass.getDeclaredConstructors();
•        for (Constructor<?> declaredConstructor : declaredConstructors) {
•            System.*out*.println(declaredConstructor);
•        }
•        System.*out*.println("~~~~~~~~");
•        *//**它只能得到本类中**public**的构造函数
\*        Constructor<?>[] constructors = qClass.getConstructors();
•        for (Constructor<?> constructor : constructors) {
•            System.*out*.println(constructor);
•        }
•    }
}
class BigQ{
•    public BigQ(){
•        System.*out*.println("父类的无参构造");
•    }
•    public BigQ(String qq){
•        System.*out*.println("父类的有参构造"+qq);
•    }
}
class Q extends BigQ{
•    public Q(){
•        System.*out*.println("子类的无参构造");
•    }
•    public Q(String name){
•        System.*out*.println("子类的有参构造"+name);
•    }
•    private Q(int age){
•        System.*out*.println("子类的有参私有构造"+age);
•    }
}

6.2 Constructor类中常用的方法

public class Test5 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        Class<Q> qClass = Q.class;
        Q q = qClass.newInstance();
        System.*out*.println("---------------");
        *//**得到无参构造
\*        Constructor<Q> declaredConstructor = qClass.getDeclaredConstructor();
        Q q1 = declaredConstructor.newInstance();
        System.*out*.println("=============");
        *//**得到有参构造
\*        Constructor<Q> declaredConstructor1 = qClass.getDeclaredConstructor(String.class);
        Q q2 = declaredConstructor1.newInstance("hello,world");
​
•    }
}
class BigQ{
•    public BigQ(){
•        System.*out*.println("父类的无参构造");
•    }
•    public BigQ(String qq){
•        System.*out*.println("父类的有参构造"+qq);
•    }
}
class Q extends BigQ{
•    public Q(){
•        System.*out*.println("子类的无参构造");
•    }
•    public Q(String name){
•        System.*out*.println("子类的有参构造"+name);
•    }
•    private Q(int age){
•        System.*out*.println("子类的有参私有构造"+age);
•    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值