编程语言
首页 > 编程语言> > Java学习_20220628

Java学习_20220628

作者:互联网

注解

1. 注解Annotation的作用:不是程序本身,可以对程序作出解释,可以被其他程序读取。可通过反射机制编程实现这些元数据的访问。 

@Override 重写的注解

@Deprecated 不推荐使用,但可以使用

@SuppressWarnings 抑制编译时的警告信息。@SuppressWarnings("all")全部警告;@SuppressWarnings("unchecked")未检查的。

2. 元注解

负责注解其他注解。4个meta-annotation:

@Target 用来描述注解的使用范围(被描述的注解可以用在什么地方)

@Retention 表示需要在什么级别保存该注释信息,用于描述注解的生命周期,表示注解在什么地方有效  

@Documented 说明该注解将被包含在javadoc中

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

Annotation通常定义

@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface MyAnnotation1 {
}

(1)使用 @interface 定义注解时,意味着它实现了java.lang.annotation.Annotation 接口,即该注解就是一个Annotation。定义 Annotation 时,@interface 是必须的。通过 @interface 定义注解后,该注解不能继承其他的注解或接口。

(2)@Documented类和方法的 Annotation 在缺省情况下是不出现在 javadoc 中的。如果使用 @Documented 修饰该 Annotation,则表示它可以出现在 javadoc 中。

(3)@Target(ElementType.TYPE),ElementType 是 Annotation 的类型属性。@Target 的作用,就是来指定 Annotation 的类型属性。
      public enum ElementType {
          TYPE,             // 类、接口(包括注释类型)或枚举声明  
          FIELD,            // 字段声明(包括枚举常量) 
          METHOD,           // 方法声明 
          PARAMETER,        //参数声明 
          CONSTRUCTOR,      // 构造方法声明  
          LOCAL_VARIABLE,   // 局部变量声明  
          ANNOTATION_TYPE,  // 注释类型声明 
          PACKAGE           //包声明 
      }
(4)@Retention(RetentionPolicy.RUNTIME)  RetentionPolicy 是 Annotation 的策略属性,而 @Retention 的作用,就是指定 Annotation 的策略属性。

    enum RetentionPolicy {
          SOURCE,    /* Annotation信息仅存在于编译器处理期间,编译器处理完之后就没有该Annotation信息了  */
          CLASS,             /* 编译器将Annotation存储于类对应的.class文件中。默认行为  */
          RUNTIME            /* 编译器将Annotation存储于class文件中,并且可由JVM读入 */
    }

  SOURCE < CLASS < RUNTIME 

public class Test01 {
    //注解可以显示赋值,若没默认值,必须给注解赋值
    @MyAnnotation1(name="张三",school = {"大学","参数"})
    public void test1(){}
  
    @MyAnnotation2("java") //可省略value=
    public void test2(){}
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation1{
    //注解的参数 : 参数类型 + 参数名();
    String name();
    String sex() default "";
    int age() default 0;//给出默认值
    String[] school();
}

@Target({ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@interface MyAnnotation2{
    String value();//只有一个参数默认用value进行命名
}

反射

1.Reflection是Java被视为动态语言的关键,可获得任何类的内部信息,并能直接操作任意对象的内部属性及方法。(private修饰的属性可操作)

正常方式:引入需要的"包类"名称——>通过new实例化——>取得实例化对象

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

一个类在内存中只有一个Class对象,一个类被加载后,类的整个结构都会被封装在Class对象中。

类继承Object类可获得getClass()方法

(1)Class类的创建方式

class Person {//父类
    public String name;
    public Person() { }
    public Person(String name) {
           this.name = name;
    }
}
class Student extends Person {//子类
     public Student() {
     this.name = "学生";
     }
}
public class RefleTest01 {
    public static void main(String[] args) throws ClassNotFoundException {
        Person person = new Student();
        System.out.println("这个人是:" + person.name);//这个人是:学生
        //方式1:通过对象获得
        Class c1 = person.getClass();
        System.out.println(c1.hashCode());//2129789493

        //方式2:forName获得
        Class c2 = Class.forName("java_basics.Annotations.Student");
        System.out.println(c2.hashCode());//2129789493

        //方式3:通过类名.class获得
        Class c3 = Student.class;
        System.out.println(c3.hashCode());//2129789493

        //方式4:基本内置类型的包装类都有一个Type属性
        Class c4 = Integer.TYPE;
        System.out.println(c4);//int

        //获取父类类型
        Class c5 = c1.getSuperclass();
        System.out.println(c5);//class java_basics.Annotations.Person
    }
}

(2)哪些类型可以有Class对象

只要元素类型与维度一样,就是同一个Class。

Class cl1 = Object.class; //类.class
Class cl2 = Comparable.class;//接口.class
Class cl3 = String[].class; //一维数组.class
Class cl4 = int[][].class; //二维数组.class
Class cl5 = Override.class; //注解.class
Class cl6 = ElementType.class;//枚举类型.class
Class cl7 = Integer.class;//基本数据类型.class
Class cl8 = void.class;//空类型
Class cl9 = Class.class; //Class

System.out.println(cl1 ); //class java.lang.Object
System.out.println(cl2 ); //interface java.lang.Comparable
System.out.println(cl3 ); //class [Ljava.lang.String;
System.out.println(cl4 ); //class [[I
System.out.println(cl5 ); //interface java.lang.Override
System.out.println(cl6 ); //class java.lang.annotation.ElementType
System.out.println(cl7 ); //class java.lang.Integer
System.out.println(cl8 ); //void
System.out.println(cl9 ); //class java.lang.Class

2. Java内存分析

3. 获得类的信息

Class c1 = Class.forName("java_basics.Extends_test.Person");
/*Person p=new Person();
c1 = p.getClass();*/

//获得类的名字
System.out.println("c1.getName() = "+c1.getName()); //包名+类名
System.out.println("c1.getSimpleName() = " + c1.getSimpleName());  //类名

//获得类的属性
Field[] fields = c1.getFields();//只能找到public属性
for (Field field : fields) {
    System.out.println(field);
}
Field[] declaredFields = c1.getDeclaredFields();//可以找到全部属性
for (Field declaredField : declaredFields) {
    System.out.println(declaredField);
}

//获得指定属性
Field de = c1.getDeclaredField(String.valueOf("score"));
Field fi = c1.getDeclaredField("name");
System.out.println(fi);
System.out.println(de);

//获得类的方法
Method[] methods = c1.getMethods();
for (Method method : methods) {
    System.out.println("正常的"+method);//获得本类及其父类的全部public方法
}
methods = c1.getDeclaredMethods();
for (Method method : methods) {
    System.out.println("    "+method); //获得本来的所有方法
}

//获得指定的方法
Method getName = c1.getMethod("getName", null);
Method setName = c1.getMethod("setName", String.class);
System.out.println("getName = " + getName);
System.out.println("setName = " + setName);

//获得构造器
Constructor[] constructors = c1.getConstructors();//获得public构造器
Constructor[] declaredConstructors = c1.getDeclaredConstructors(); //获得全部的构造器

//获得指定的构造器
Constructor deCons = c1.getDeclaredConstructor(double.class, String.class, int.class);
System.out.println(deCons);

 4. 反射(使用Class对象的newInstance()方法)创建类的对象 

public class RefleTest03 {
    public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, NoSuchFieldException {
        //获得class对象
        Class c1 = Class.forName("java_basics.Annotations.User");
        //构造一个对象
        User user = (User) c1.getDeclaredConstructor().newInstance();//本质上是调用了无参构造器
        System.out.println(user);  //User{name='null', age=0, id=0}
        //通过构造器创建对象
        Constructor  constructor = c1.getDeclaredConstructor(String.class, int.class, int.class);
        User user1 = (User) constructor.newInstance("张三", 15, 20220628);
        System.out.println("user1 = " + user1); //user1 = User{name='张三', age=15, id=20220628}
        //通过反射调用普通方法
        User user2 = (User) c1.getDeclaredConstructor().newInstance();
        //通过反射获取一个方法
        Method setName = c1.getDeclaredMethod("setName", String.class);
        //invoke:激活   (对象,“方法的值”)
        setName.invoke(user2,"李四");
        System.out.println("user2.getName() = " + user2.getName());//user2.getName() = 李四
        //通过反射操作属性
        User user3 = (User) c1.getDeclaredConstructor().newInstance();
        Field name = c1.getDeclaredField("name");
        //不能直接操作私有属性,需要关闭程序的安全检测,属性/方法.setAccessible(true);
        name.setAccessible(true);
        name.set(user3,"王五");
        System.out.println("user3.getName() = " + user3.getName()); //user3.getName() = 王五
    }
}

通过反射获取泛型

//通过反射获取泛型
public class RefleTest04 {
    public void test01(Map<String,User> map, List<User> list){
        System.out.println("test01");
    }
    public Map<String,User> test02(){
        System.out.println("test02");
        return null;
    }
    public static void main(String[] args) throws NoSuchMethodException {
        Method method = RefleTest04.class.getMethod("test01", Map.class, List.class);
        Type[] genericParameterTypes = method.getGenericParameterTypes();//获得泛型的参数信息

        for (Type genericParameterType : genericParameterTypes) {
            System.out.println("genericParameterTypes = " + genericParameterTypes);
            //知道参数类型中的类型
            if(genericParameterType instanceof ParameterizedType){  //是否是参数化类型
                Type[] actualTypeArguments = ((ParameterizedType) genericParameterType).getActualTypeArguments();//获得真实参数类型
                for (Type actualTypeArgument : actualTypeArguments) {
                    System.out.println("actualTypeArgument = " + actualTypeArgument);
                }
            }
        }
        method = RefleTest04.class.getMethod("test02",null);
        Type genericReturnType = method.getGenericReturnType();//获取返回值类型
        if(genericReturnType instanceof ParameterizedType){  //是否是参数化类型
            Type[] actualTypeArguments = ((ParameterizedType) genericReturnType).getActualTypeArguments();//获得真实参数类型
            for (Type actualTypeArgument : actualTypeArguments) {
                System.out.println("actualTypeArgument = " + actualTypeArgument);
            }
        }
    }
}

5. 反射操作注解

利用注解和反射完成类和表结构的映射关系

//对类名的注解
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@interface TableName{ 
    String value();
}
//对属性的注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@interface FieldName{
    String columnName();
    String type();
    int length();
}
//定义类
@TableName("db_student")
class Students{
    @FieldName(columnName = "db_id",type ="int",length = 8)
    private int id;
    @FieldName(columnName = "db_name",type ="varchar",length = 3)
    private String name;
    @FieldName(columnName = "db_age",type ="int",length = 2)
    private int age;
    public Students() {
    }
    public Students(int id,String name,int age){
        this.id=id;
        this.name=name;
        this.age=age;
    }
    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Students{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
public class RefleTest05{
    public static void main(String[] args) throws ClassNotFoundException, NoSuchFieldException {
        Class c1 = Class.forName("java_basics.Annotations.Students");
        //通过反射获得注解
        Annotation[] annotations = c1.getAnnotations();
        for (Annotation annotation : annotations) {
            System.out.println(annotation);//@java_basics.Annotations.TableName(value="db_student")
        }
        //获得注解的value的值
        TableName tableName = (TableName)c1.getAnnotation(TableName.class);//获取指定的注解
        System.out.println("tableName.value() = " + tableName.value());//tableName.value() = db_student

        //获取类指定的注解
        Field f = c1.getDeclaredField("name");//获得属性
        FieldName annotation = f.getAnnotation(FieldName.class);//获得属性的注解
        System.out.println("annotation.columnName() = " + annotation.columnName());//annotation.columnName() = db_name
        System.out.println("annotation.type() = " + annotation.type());//annotation.type() = varchar
        System.out.println("annotation.length() = " + annotation.length());//annotation.length() = 3
    }
}

 

标签:Java,20220628,System,public,学习,println,c1,class,out
来源: https://www.cnblogs.com/Joyce-mi7/p/16418837.html