反射

代码1

/*
获取Class对象的四种方式
* */
public class Demo1 {
    public static void main(String[] args) throws ClassNotFoundException {
        //第一种
        Class aClass=Person.class;

        //第二种
        Person p=new Person();
        Class aClass2=p.getClass();

        //第三种
        Class aClass3=aClass.getClassLoader().getClass();

        //第四种
        Class aClass4=Class.forName("com.atguigu.day18.Person");
    }
}

class Person{

}

代码2

反射创建构造器

package com.atguigu.day18;

import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
import java.util.Scanner;

/*
使用反射创建对象

* */
public class Demo2 {
    //无参数构造器
    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
        //获取对应的Class对象
        Scanner sc = new Scanner(System.in);
        System.out.println("输入要创建的类名:");//com.atguigu.day18.Persons
        String className = sc.next();
        Class clazz = Class.forName(className);

        //创建对象,调用了对应类型的无参构造器
        Object obj = clazz.newInstance();
        System.out.println(obj);//Persons
    }

    //普通参数构造器
    @Test
    public void test1() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //调用有参构造器完成对成员的初始化
        //1.获取Class对象
        Class clazz = Class.forName("com.atguigu.day18.Persons");

        Constructor[] c = clazz.getDeclaredConstructors();
        for (Constructor constructor : c) {
            System.out.println(constructor);
            /*输出有参和无参的构造器
            public com.atguigu.day18.Persons()
            public com.atguigu.day18.Persons(java.lang.String)
            * */
        }

        //2.获取构造器
        //获取一个参数的构造器,放的是参数的Class
        Constructor constructor=clazz.getConstructor(String.class);

        //3.执行构造器
        Object instance = constructor.newInstance("贾政");
        //4.输出结果
        System.out.println(instance);//Persons{name='贾政'}
    }

    //私有构造器
    @Test
    public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
        //获取Class对象
        Class clazz = Class.forName("com.atguigu.day18.Persons");
        //获取构造器
        //Constructor constructor=clazz.getConstructor(String.class,int.class);//非私有的构造器可以这样调用
        Constructor constructor=clazz.getDeclaredConstructor(String.class, int.class);//私有的构造器这样调用
        //设置私有的构造器可以访问
        constructor.setAccessible(true);
        //执行构造器
        Object object=constructor.newInstance("贾琏",17);
        //输出结果
        System.out.println(object);//Persons{name='贾琏', age=17}
    }
}

class Persons{
    String name="贾宝玉";
    int age;

    public Persons() {
    }

    public Persons(String name) {
        this.name = name;
    }

    private Persons(String name, int age) {
        this.name = name;
        this.age = age;
    }

    @Override
    public String toString() {
        return "Persons{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}

代码3

反射调用属性

package com.atguigu.day18;

import org.junit.Test;

import java.lang.reflect.Field;

public class Demo3 {
    //获取属性
    @Test
    public void test1() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获取对应的Class对象
        Class clazz = Class.forName("com.atguigu.day18.Students");
        //获取属性
        Field gender=clazz.getField("gender");
        //创建对象
        Object object=clazz.newInstance();
        //获取属性值
        Object object1=gender.get(object);
        System.out.println(object1);//man
    }

    //获取静态属性
    @Test
    public void test2() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获取对应的Class对象
        Class clazz = Class.forName("com.atguigu.day18.Students");
        //获取属性
        Field country=clazz.getField("country");
        //创建对象
        Object object=clazz.newInstance();
        //获取属性值
        Object object1=country.get(null);
        System.out.println(object1);//中国
    }
    //获取私有属性
    @Test
    public void test3() throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException {
        //获取对应的Class对象
        Class clazz = Class.forName("com.atguigu.day18.Students");
        //获取属性值
        Field nameField=clazz.getDeclaredField("name");
        //设置私有属性可见
        nameField.setAccessible(true);
        //创建对象
        Object object=clazz.newInstance();
        nameField.set(object,"李白白");//修改私有属性值
        //获取属性值
        Object object1=nameField.get(object);
        System.out.println(object1);//如果修改私有属性值则为李白白,不修改则为李白
    }
}

class Students{
    public static String country="中国";
    private String name="李白";
    double height=1.78;
    public String gender="man";

    @Override
    public String toString() {
        return "Students{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", gender='" + gender + '\'' +
                '}';
    }
}

代码4

反射调用方法

package com.atguigu.day18;

import org.junit.Test;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

public class Demo4 {
    //静态方法
    @Test
    public void test1() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //获取Class对象
        Class clazz=Class.forName("com.atguigu.day18.Rapper");
        //获取指定方法
        Method method=clazz.getDeclaredMethod("show");
        //创建对象
        Object object=clazz.newInstance();
        //执行方法
        method.invoke(null);//静态show方法
    }

    //普通有参方法
    @Test
    public void test2() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //获取Class对象
        Class clazz=Class.forName("com.atguigu.day18.Rapper");
        //获取方法
        Method method=clazz.getDeclaredMethod("getSum", int.class, int.class);
        //创建对象
        Object object=clazz.newInstance();
        //执行方法
        method.invoke(object,1,3);//a+b=4
    }

    //私有方法
    @Test
    public void test3() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InstantiationException, InvocationTargetException {
        //获取Class对象
        Class clazz=Class.forName("com.atguigu.day18.Rapper");
        //获取方法
        Method method=clazz.getDeclaredMethod("showMessage");
        method.setAccessible(true);
        //创建对象
        Object object=clazz.newInstance();
        //调用方法
        method.invoke(object);//私有showMessage方法
    }
}

class Rapper{
    public static String country="中国";
    private String name="李白";
    double height=1.78;
    public String gender="man";

    public void getSum(int a,int b){
        System.out.println("a+b="+(a+b));
    }

    public static void show(){
        System.out.println("静态show方法");
    }

    private void showMessage(){
        System.out.println("私有showMessage方法");
    }

    @Override
    public String toString() {
        return "Rapper{" +
                "name='" + name + '\'' +
                ", height=" + height +
                ", gender='" + gender + '\'' +
                '}';
    }
}

代码5

 反射调用注解

<1>注解代码

package com.atguigu.day18;

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target({ElementType.FIELD,ElementType.METHOD,ElementType.TYPE,ElementType.CONSTRUCTOR})
@Retention(RetentionPolicy.RUNTIME)//可以存活到运行时的注解
public @interface MyAnnotation {
    String value() default "这是默认注解";//如果没有定义的value则是默认的value
}

<2>代码

package com.atguigu.day18;


import org.junit.Test;

import java.lang.annotation.Annotation;
import java.lang.annotation.Target;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class Demo5 {
    @Test
    public void test1() throws ClassNotFoundException, NoSuchMethodException, NoSuchFieldException {
        //获取Class对象
        Class clazz=Class.forName("com.atguigu.day18.Father");
        //获取类注解
        Annotation[] annotations=clazz.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);//@com.atguigu.day18.MyAnnotation(value=父类)
        }

        //获取类注解
        Annotation annotations2=clazz.getAnnotation(MyAnnotation.class);
        System.out.println(annotations2);//@com.atguigu.day18.MyAnnotation(value=父类)

        //获取方法注解
        Method method=clazz.getDeclaredMethod("show");
        Annotation methodAnno=method.getDeclaredAnnotation(MyAnnotation.class);
        System.out.println(methodAnno);//@com.atguigu.day18.MyAnnotation(value=父类方法)

        //获取属性注解
        Field field=clazz.getDeclaredField("name");
        Annotation fieldAnno=field.getDeclaredAnnotation(MyAnnotation.class);
        System.out.println(fieldAnno);//@com.atguigu.day18.MyAnnotation(value=父类属性)

        //获取构造器注解
        Constructor constructor=clazz.getDeclaredConstructor();
        Annotation constructorAnno=constructor.getAnnotation(MyAnnotation.class);
        System.out.println(constructorAnno);//@com.atguigu.day18.MyAnnotation(value=父类构造器)
    }

}

@MyAnnotation(value = "父类")
class Father{
    @MyAnnotation(value = "父类属性")
    String name="name1";

    @MyAnnotation(value = "父类构造器")
    public Father() {
    }

    @MyAnnotation(value = "父类方法")
    public void show(){
        System.out.println("show method");
    }
}

class Son extends Father{
    @Override
    public void show() {
        System.out.println("son show method");
    }
}

代码6

反射突破泛型限制

import java.lang.reflect.Array;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Date;

/*
使用反射突破泛型限制
* */
public class Demo6 {
    public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        ArrayList<String> list = new ArrayList<>();
        list.add("just1");
        //获取对象类
        Class clazz=list.getClass();
        Method addMethod=clazz.getDeclaredMethod("add", Object.class);

        addMethod.invoke(list,new Date());
        addMethod.invoke(list,1999);

        System.out.println(list);//[just1, Tue Jan 25 22:14:12 CST 2022, 1999]
    }
}

代码7

使用泛型创建数组

import org.junit.Test;

import java.lang.reflect.Array;

/*
使用反射创建数组
* */
public class Demo7 {
    @Test
    public void test1(){
       //创建一个数组,长度是5
       Object object= Array.newInstance(String.class,5);
        System.out.println(object);//[Ljava.lang.String;@4ee285c6

        //添加元素
        Array.set(object,0,"name1");
        Array.set(object,1,"name2");

        Object object1=Array.get(object,1);
        System.out.println(object1);//name2
    }
}

 

posted @ 2022-01-25 11:42  从此重新定义啦  阅读(17)  评论(0编辑  收藏  举报