反射总结笔记,注解 : Annotation , Java8新特性--函数式接口

本文深入探讨了Java的反射机制,包括在运行时动态获取类信息、创建对象、调用方法和操作属性。同时,介绍了Java的函数式接口,如Consumer、Supplier和Predicate,展示了它们在实际代码中的应用。通过示例代码,详细阐述了反射和函数式接口的使用方法,帮助读者理解这两项核心技术。
摘要由CSDN通过智能技术生成

反射:
        发生在程序运行期间的动态机制|行为
        是java的唯一动态机制-->反射机制
 */
public class Class001_Reflect {

    public static void main(String[] args) throws ClassNotFoundException, IllegalAccessException, InstantiationException, IOException {
        //11新特性: 局部变量可以使用var声明
        var i  = 1;

        i=5;

        //Properties对象
        Properties pro = new Properties();

        //从流中加载
        pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("classname.properties"));

        //通过反射创建对象
        Person obj = (Person) Class.forName(pro.getProperty("classname")).newInstance();
        obj.test();

    }
}


class Person{
    void test(){
        System.out.println("Person");
    }
}

class Student extends Person{
    void test(){
        System.out.println("Student");
    }
}
class Teacher extends Person{
    void test(){
        System.out.println("Teacher");
    }
}

  **Java反射机制,可以实现以下功能:**

        ①在运行时判断任意一个对象所属的类;

        ②在运行时构造任意一个类的对象;

        ③在运行时判断任意一个类所具有的成员变量和方法;

        ④在运行时调用任意一个对象的方法;

        ⑤生成动态代理;

        *

    反射的源头:
    *   Class<T> Class类型的实例可以用来表示java中运行期间的一个类型
    *   Class对象
    *
    *   Class对象在类第一次加载到内存后就已经存在的,唯一的,不变的,每一个类型只有一个
    *   Class对象可以操作这个类的所有内容(属性方法构造器...)
    *
    如何获取反射的源头:Class对象
    *   1.类名.class
    *   2.Class.forName(权限定名)  权限定名:包名.类名   -->推荐
    *   3.对象.getClass()
 */
public class Class002_Reflect {
    public static void main(String[] args) throws ClassNotFoundException {
        //1.类名.class
        Class<String> cls1 = String.class;
        System.out.println(cls1.toString());

        //2.Class.forName(权限定名)
        Class cls2 = Class.forName("java.lang.String");
        System.out.println(cls2);
        System.out.println(cls2==cls1);

        //3.对象.getClass()
        Class cls3 = "abc".getClass();
        System.out.println(cls3);
        System.out.println(cls3==cls1);

        //获取当前Class对象所表示类型的父类的Class对象
        Class cls4 = cls1.getSuperclass();
        System.out.println(cls4);
        System.out.println(cls4==Object.class);

        //获取基本数据类型的Class对象
        System.out.println(Integer.class);
        System.out.println(int.class);
        System.out.println(int.class==Integer.class);
        System.out.println(Integer.TYPE);
        System.out.println(Integer.TYPE==int.class);
    }
}

 反射操作构造器
        构造器<T> getConstructor(类<?>... parameterTypes) 返回一个 构造器对象,该对象反映此 类对象所表示的类的指定公共构造函数。
        构造器<?>[] getConstructors() 返回一个包含 构造器对象的数组, 构造器对象反映了此 类对象所表示的类的所有公共构造函数。
        以上都是获取公共的,被public修饰的构造器
        构造器<T> getDeclaredConstructor(类<?>... parameterTypes) 返回一个 构造器对象,该对象反映此 类对象所表示的类或接口的指定构造函数。
        构造器<?>[] getDeclaredConstructors() 返回 构造器对象的数组, 构造器对象反映由此 类对象表示的类声明的所有构造函数。

    反射创建对象
        Class-->T newInstance()  默认调用类型的空构造为对象初始化信息  -->不推荐使用
            不能确定一个类型是否存在空构造,极有可能遇到运行时异常
        Constructor---> T newInstance(Object... initargs) 创建对象的同时调用当前构造器为对象初始化信息

 */
public class Class003_Reflect {
    public static void main(String[] args) throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {


        //获取构造器
        Class<User> cls = User.class;

        Constructor[] cons =  cls.getConstructors();
        for(Constructor con:cons){
            System.out.println(con);
        }

        Constructor<User> con = cls.getDeclaredConstructor(String.class,int.class);
        System.out.println(con);

        //创建对象
        //1)
        User user =  User.class.newInstance();
        System.out.println(user);

        //2) 私有内容需要忽略权限使用
        con.setAccessible(true);  //忽略权限
        User user2 = con.newInstance("laopei",1234);
        System.out.println(user2);
    }


}

class User{
    private String name;
    private int pwd;

    //公共的
    public User() {
    }

    public User(String name) {
        this.name = name;
    }
    //私有的
    private User(String name, int pwd) {
        this.name = name;
        this.pwd = pwd;
    }

    public String getName() {
        return name;
    }

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

    public int getPwd() {
        return pwd;
    }

    public void setPwd(int pwd) {
        this.pwd = pwd;
    }

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

}

反射操作属性
        字段 getField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定公共成员字段。
        字段[] getFields() 返回一个包含 字段对象的数组, 字段对象反映此 类对象所表示的类或接口的所有可访问公共字段。
        字段 getDeclaredField(String name) 返回 字段对象,该对象反映此 类对象表示的类或接口的指定声明字段。
        字段[] getDeclaredFields() 返回 字段对象的数组, 字段对象反映由此 类对象表示的类或接口声明的所有字段。

        void set(Object obj, Object value) 将指定对象参数上此 字段对象表示的字段设置为指定的新值。
        Object get(Object obj) 返回指定对象上此 字段表示的字段的值。

    反射操作方法
        方法 getMethod(String name, 类<?>... parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定公共成员方法。
        方法[] getMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象所表示的类或接口的所有公共方法,包括由类或接口声明的那些以及从超类和超接口继承的那些。
        方法 getDeclaredMethod(String name, 类<?>... parameterTypes) 返回 方法对象,该对象反映此 类对象表示的类或接口的指定声明方法。
        方法[] getDeclaredMethods() 返回一个包含 方法对象的数组, 方法对象反映此 类对象表示的类或接口的所有已声明方法,包括public,protected,default(package)访问和私有方法,但不包括继承的方法。

        Object invoke(Object obj, Object... args) 在具有指定参数的指定对象上调用此 方法对象表示的基础方法。

 */
public class Class004_Reflect {
    public static void main(String[] args) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        User user = new User("zhangsan");

        //User类的Class对象
        Class<User> cls = User.class;

        testMethod(cls,user);

    }

    //测试方法
    public static void testMethod(Class<User> cls,User user) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        Method[] methods = cls.getMethods();
        for(Method m:methods){
            System.out.println(m);
        }

        //私有方法
        Method method = cls.getDeclaredMethod("haha",int.class);

        //调用方法
        method.setAccessible(true);
        System.out.println(method.invoke(user,100));;
        System.out.println(method.invoke(null,100));;

        Method m = cls.getMethod("getName");
        System.out.println(m.invoke(user));
    }

    //测试属性
    public static void testField(Class<User> cls,User user) throws NoSuchFieldException, IllegalAccessException {
        Field field = cls.getDeclaredField("name");

        System.out.println(field.getName());
        System.out.println(field.getType());

        //忽略权限
        field.setAccessible(true);

        field.set(user,"zhangsanfeng");

        System.out.println(field.get(user));
    }

}

反射操作数组
        static Object newInstance(类<?> componentType, int length) 创建具有指定组件类型和长度的新数组。
        static Object get(Object array, int index) 返回指定数组对象中索引组件的值。
        static void set(Object array, int index, Object value) 将指定数组对象的索引组件的值设置为指定的新值。
   反射常用方法


 */
public class Class005_Reflect {
    public static void main(String[] args) throws Exception {
        testArray();

        test(String.class);

    }
    public static void test(Class<String> cls){
        //int getModifiers() 返回此类或接口的Java语言修饰符,以整数编码。
        System.out.println(cls.getModifiers());
        System.out.println(Modifier.toString(cls.getModifiers()));

        //类<?>[] getInterfaces() 返回由此对象表示的类或接口直接实现的接口。
        System.out.println(Arrays.toString(cls.getInterfaces()));

        //String getName() 返回此 类对象表示的实体名称(类,接口,数组类,基本类型或void),作为 String 。
        System.out.println(cls.getName());

        //String getSimpleName() 返回源代码中给出的基础类的简单名称。
        System.out.println(cls.getSimpleName());
    }

    //简单操作数组
    public static void testArray(){
        int[] arr = (int[]) Array.newInstance(int.class,5);

        Array.set(arr,2,200);

        System.out.println(Arrays.toString(arr));

        System.out.println(Array.get(arr,2));
    }
}

注解 : Annotation
        标注

        java8引入的注解机制

    作用:
         1.注释
         2.标志|标识
         3.使用注解时可以传递参数,可以在程序中通过反射操作注解,获取配置的信息在程序中使用
         4.可以存在于Class文件中
         5.大量的代替|简化配置文件的使用


    使用:
        @注解名(参数)

    注解的分类:
        jdk的内置注解 : 常见
            @Override 检查重写方法
            @SuppressWarnings("all") 抑制警告
            @Deprecated 表示已过时,不推荐使用
            @FunctionalInterface 标识函数式接口

        参数的个数分类:
                标志|标识注解
                单值注解
                完整注解
       

 元注解 : 注解注解的注解

元注解 : 就是负责注解其他注解
    1)@Target 用于描述注解的使用范围
    2)@Retention 规定注解类型的声明周期
    3)@Documented 保留在API文档中
    4)@Inherited 标识注解类型可以被继承


  自定义注解

1.@interface 定义注解类型
2.默认实现java.lang.annotation.Annotation接口
3.自定义的注解类型就不能显示的继承其他父类,实现其他接口
4.如果注解类中的属性只有一个,建议名字为value,为value属性赋值可以直接赋值
5.为注解类型定义属性|字段: 数据类型 数据名();
6.属性的数据类型要求为: 基本数据类型 String, 枚举 , 注解类型 , 以及以上类型的数组
7.属性可以通过default提供默认值

 函数式接口
        接口中只与一个必须被重写的抽象方法
        @FunctionalInterface

    四大内置函数式接口:
        1.消费型接口  Consumer<T>
            void accept(T t)   --> 有来无回,有参数没有返回值
        2.供给型接口  Supplier<T>
            T get()
        3.函数型接口  Function<T,R>
            R apply(T t)
        4.段言型接口  Predicate<T>
            boolean test(T t)
public class Class001_FunctionalInterface {
    public static void main(String[] args) {
        testConsumer(5000, m-> System.out.println("今天在薇娅直播间为鸿星尔克消费"+m));
        testConsumer(10000, m-> System.out.println("今天在李佳琪直播间为鸿星尔克消费"+m));

        System.out.println(getNum(5,()->(int)(Math.random()*(5-1+1)+1)));;
        System.out.println(getNum(3,()->(int)(Math.random()*(15-10+1)+10)));;

        System.out.println(strHandler("   haha  ",s->s.trim()));;
        System.out.println(strHandler("   haha  ",s->s.toUpperCase()));;

        List<Employee> list = new ArrayList<Employee>();

        list.add(new Employee(1003,"zhangsan",19));
        list.add(new Employee(1002,"lisi",17));
        list.add(new Employee(1001,"wangwu",18));

        System.out.println(checkEmp(list,e->e.getAge()>=18));
    }

    //对员工集合中的员工数据按照某种规则进行过滤,返回结果
    public static List<Employee> checkEmp(List<Employee> list, Predicate<Employee> predicate){
        List<Employee> newList = new ArrayList<>();
        for(Employee e:list){
            if(predicate.test(e)){
                newList.add(e);
            }
        }
        return newList;
    }

    //对字符串进行处理,返回结果
    public static String strHandler(String str, Function<String,String> my){
        return my.apply(str);
    }

    //产生指定个数的指定规则的随机数
    public static List<Integer> getNum(int num, Supplier<Integer> supplier){
        List<Integer> list = new ArrayList<>();
        for(int i=1;i<=num;i++){
            list.add(supplier.get());
        }
        return list;
    }

    //消费的功能
    public static void testConsumer(int money, Consumer<Integer> con){
        con.accept(money);
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值