当前位置: 主页 > JAVA语言

java实体默认值-java反射的优缺点有哪些?-八维java培训

发布时间:2023-06-26 10:07   浏览次数:次   作者:佚名

TYPE_USE

作用范围:任意使用类型的地方

@Retention:表示需要在什么级别保存该注解信息,用于描述注解的生命周期(SOURCE

类型

描述

SOURCE

生命周期只保留在源码

CLASS

java变量默认权限uml_java默认十进制_java实体默认值

生命周期保留到.class编译阶段

RUNTIME

生命周期保留到jvm运行阶段

@Document:说明该注解将被包换在javadoc中

@Inherited:说明子类可以继承父类中的注解

4.自定义注解

java变量默认权限uml_java默认十进制_java实体默认值

使用@Interface自定义注解时,自动继承了java.lang.annotation接口

package com.xiaoxian.missyou.annotion;
import java.lang.annotation.*;
@MyAnnotion(num = 0,friends = {"123","456"})
    public class AnnotionTest {
    }
@Target({ElementType.TYPE,ElementType.METHOD,ElementType.FIELD})
    @Retention(RetentionPolicy.RUNTIME)
    @Documented
    @Inherited
    @interface MyAnnotion{
        String name() default "";
        int num();
        String[] friends() default {"123","456"};
    }

二、反射1.什么是反射

Reflection(反射)是Java被视为动态语言的关键,反射机制允许程序在执行期间借助Reflection API取得任何类得内部信息,并能直接操作任意对象的内部属性及方法。

类加载完后,在堆内存的方法区中就产生一个Class类型的对象(一个类只有一个Class对象),这个对象就包含了完整的类的结构信息。

正常方式:引入包名 ---> new实例化 ----> 取得实例化对象

java变量默认权限uml_java默认十进制_java实体默认值

反射方式:实例化对象 -----> getClass()方法 ------> 得到完整的包名

2.反射机制提供的功能3.反射的优缺点

优点:可以实现动态创建对象和编译,体现出很大的灵活性。

缺点:对性能有影响,这类操作总是慢于直接执行相同的操作。通过invoke()调用方法的时候,可以先使用setAccessible(true)方法,取消java语言访问检查java实体默认值,可以提高一点点性能。

4.通过反射获取class对象

package com.xiaoxian.missyou.inject;
import lombok.Data;
public class Test1 {
    public static void main(String[] args) throws ClassNotFoundException {
        Class c1 = Class.forName("com.xiaoxian.missyou.inject.Student");
        Class c2 = Class.forName("com.xiaoxian.missyou.inject.Student");
        //获取的classd对象都是同一个对象,因为只有一个class对象
        System.out.println(c1.hashCode());
        System.out.println(c2.hashCode());
        Person person = new Student();
        //方式一:通过对象获取class对象
        Class c3 = person.getClass();
        System.out.println(c3.hashCode());
        //方式二:forname()获取class对象
        Class c4 = Class.forName("com.xiaoxian.missyou.inject.Student");
        System.out.println(c4.hashCode());
        //方式三:通过类名.class获取class对象
        Class c5 = Student.class;
        System.out.println(c5.hashCode());
        //方式四:基本类型的包装类可以通过Type属性获取class对象
        Class c6 = Integer.TYPE;
        System.out.println(c6.hashCode());
        //获取父类的class对象
        Class c7 = c3.getSuperclass();
        System.out.println(c7.hashCode());
    }
}
@Data
    class Person {
        private String name;
    }
@Data
    class Student extends Person{
        private Integer age;
    }

java默认十进制_java变量默认权限uml_java实体默认值

5.哪些类型可以有Class对象

package com.xiaoxian.missyou.inject;
  
  import java.lang.annotation.ElementType;
  import java.util.Map;
  
  public class Test2 {
      public static void main(String[] args) {
          
          Class c1 = Object.class;//类
  
          Class c2 = Map.class;//接口
  
          Class c3 = String[].class;//一维数组
  
          Class c4 = String[][].class;//二维数组
  
          Class c5 = Override.class;//注解
  
          Class c6 = ElementType.class;//枚举
  
          Class c7 = Integer.class;//基本数据类型
  
          Class c8 = void.class;//void
  
          Class c9 = Class.class;//class
      }
  }

6.获取运行时类的完整结构

package com.xiaoxian.missyou.inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test3 {
    public static void main(String[] args) throws NoSuchFieldException, NoSuchMethodException {
        Class c1 = Student.class;
        //获取类的名字
        System.out.println(c1.getName());//获取 包名+类名
        System.out.println(c1.getSimpleName());//获取类名
        //获取类的属性
        System.out.println("================================");
        Field[] fields = c1.getFields();//只能获取public的属性
        for (Field field : fields) {
            System.out.println(field);
        }
        System.out.println("================================");
        Field[] declaredFields = c1.getDeclaredFields();//获取全部属性
        for (Field declaredField : declaredFields) {
            System.out.println(declaredField);
        }
        //获取指定属性
        Field age = c1.getDeclaredField("age");
        System.out.println(age);
        //获取类的方法
        System.out.println("================================");
        Method[] methods = c1.getMethods();//获取本类+父类的全部public方法
        for (Method method : methods) {
            System.out.println(method);
        }
        Method[] declaredMethods = c1.getDeclaredMethods();//获取本类所有方法
        for (Method declaredMethod : declaredMethods) {
            System.out.println(declaredMethod);
        }
        //获取指定的方法
        Method getAge = c1.getMethod("getAge", null);
        Method setAge = c1.getMethod("setAge", Integer.class);
        System.out.println(getAge);
        System.out.println(setAge);
        //获取构造方法
        System.out.println("================================");
        Constructor[] constructors = c1.getConstructors();//获取public的构造方法
        for (Constructor constructor : constructors) {
            System.out.println(constructor);
        }
        Constructor[] declaredConstructors = c1.getDeclaredConstructors();//获取全部的构造方法
        for (Constructor declaredConstructor : declaredConstructors) {
            System.out.println(declaredConstructor);
        }
        Constructor declaredConstructor = c1.getDeclaredConstructor();
        System.out.println("指定构造器:" + declaredConstructor);
    }
}

7.动态创建对象执行方法

package com.xiaoxian.missyou.inject;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test4 {
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, NoSuchFieldException {
        Class c1 = Student.class;
        //方式一:本质调用了类的无参构造函数,并且要求该无参构造函数为public
        Student student = (Student)c1.newInstance();
        System.out.println(student);
        //方式二:通过构造器创建对象
        Constructor constructor = c1.getDeclaredConstructor(Integer.class);
        Student student2 = (Student) constructor.newInstance(18);
        System.out.println(student2);
        //通过反射调用普通方法
        Method setAge = c1.getDeclaredMethod("setAge", Integer.class);
        setAge.invoke(student, 19);
        System.out.println(student.getAge());
        //通过反射操作属性
        System.out.println("==========================================");
        Field age = c1.getDeclaredField("age");
        //不能直接操作私有属性,我们需要关闭程序的安全检测,属性或者方法的setAccessible(true)
        age.setAccessible(true);
        age.set(student, 20);
        System.out.println(student.getAge());
    }
}

java默认十进制_java变量默认权限uml_java实体默认值

注意:Object invoke(Object obj,Object ... args)

8.通过反射获取泛型

为了通过反射操作这些类型,Java新增了ParameterizedTypejava实体默认值,GenericArrayType,TypeVariable和WidcardType几种类型来代表不能被归一到Class类中的类型但是又和原始类型齐名的类型。

package com.xiaoxian.missyou.inject;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.Map;
public class Test5 {
    public void test01(Map map, List list) {
        System.out.println("test01");
    }
    public Map test02() {
        System.out.println("test02");
        return null;
    }
    public static void main(String[] args) throws NoSuchMethodException {
        Class c1 = Test5.class;
        Method test01 = c1.getDeclaredMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = test01.getGenericParameterTypes();
        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("===" + genericParameterType);
            if (genericParameterType instanceof ParameterizedType) {
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println(actualTypeArgument);
                }
            }
        }
        System.out.println("=======================================");
        Method test02 = c1.getDeclaredMethod("test02");
        Type genericReturnType = test02.getGenericReturnType();
        if (genericReturnType instanceof ParameterizedType) {
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println(actualTypeArgument);
            }
        }
    }
}

java实体默认值_java默认十进制_java变量默认权限uml

9.通过反射操作注解

package com.xiaoxian.missyou.inject;
import lombok.Data;
import java.lang.annotation.*;
import java.lang.reflect.Field;
public class Test6 {
    public static void main(String[] args) {
        Class c1 = User.class;
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);
        }
        //获取指定的注解的值
        MyTable myTable = (MyTable)c1.getAnnotation(MyTable.class);
        System.out.println(myTable.value());
        //获取类上字段的注解
        Field[] declaredFields = c1.getDeclaredFields();
        for (Field declaredField : declaredFields) {
            System.out.println("=======================");
            MyField myField = (MyField) declaredField.getAnnotation(MyField.class);
            System.out.println(myField.columnName());
            System.out.println(myField.type());
            System.out.println(myField.length());
        }
    }
}
@Data
    @MyTable("db_user")
    class User{
        @MyField(columnName = "db_user_id", type = "Long", length = 10)
        private Long id;
        @MyField(columnName = "db_user_name", type = "String", length = 128)
        private String name;
    }
@Target(ElementType.TYPE)
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyTable {
        String value();
    }
@Target(ElementType.FIELD)
    @Retention(RetentionPolicy.RUNTIME)
    @interface MyField {
        String columnName();
        String type();
        int length();
    }

java变量默认权限uml_java默认十进制_java实体默认值