Java SE

Scanner类

1、需要传参:System.in

2、scanner.next()接收字符串类型

3、scanner.nextInt()接收整型

复制代码
package com.ke.demo1;

import java.util.Scanner;

public class demo1 {
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        System.out.println("输入姓名:");
        String name=scanner.next();
        System.out.println(name);
        System.out.println("输入年龄:");
        int age=scanner.nextInt();
        System.out.println(age);

    }
}
View Code
复制代码

 反射

 

一、反射相关的概念

1.什么是反射

 

 反射即反向探知,有点像考古学家根据发掘的物品来探知以前的事情

Java中的反射指的是程序在运行状态中

  1. 对于给定的一个类(Class)对象,可以获取到这个类(Class)对象的所有的属性和方法

  2. 对于给定的一个对象(new XXXClassName<? extends Object>),都能够调用它的任意一个属性和方法

这种动态获取类的内容以及动态调用对象的方法和属性的机制,就叫做Java的反射机制。

 

Java反射的优缺点:

优点:

  1. 增加程序的灵活性,避免将固有的逻辑程序写死在代码里面。

  2. 代码简洁,可读性增强,可提高代码的复用率

 

缺点:

  1. 相较于直接调用在量大的情况下反射性能下降厉害

  2. 内部暴露和安全隐患

2.Class的组成

一个Class实例包含的内容有哪些呢?

我们在程序运行的时候获取到Class类型,我们要根据Class类型来获取相关的内容

 

二、Class的基本操作

1.怎么获取Class对象

复制代码
package com.keke.reflection;

public class ReflectionDemo01 {
    @SuppressWarnings("all")
    public static void main(String[] args) throws ClassNotFoundException {
        //获取Person对应的Class对象
        Class<Person> class1 = Person.class;
        System.out.println(class1);
        Class class2 = Class.forName("com.keke.reflection.Person");
        System.out.println(class2);
        //通过Person对象中的getclass方法获取
        Person p = new Person();
        Class<? extends Person> class3 = p.getClass();
        System.out.println(class3);
        //系统提供的一些类型获取 Class对象
        Class<String> stringClass = String.class;
        Class<Integer> integerClass = int.class;
        Class<int[]> aClass = int[].class;
        System.out.println(stringClass);
        System.out.println(integerClass);
        System.out.println(aClass);
        Class<double[]> aClass1 = double[].class;
        System.out.println(aClass1);
        //获取包装类对应的class对象
        Class<Integer> integerClass1 = Integer.class;
        Class<Integer> type = Integer.TYPE;
        //获取void没有返回结果的class类型
        Class<Void> voidClass = Void.class;
        Class<Void> type1 = Void.TYPE;
        System.out.println(integerClass1);
        System.out.println(type);
        System.out.println(type1);
        System.out.println(voidClass);
    }

}
View Code
复制代码

 

 

 

注解:

一、注解相关的概念

1.概念介绍

注解:说明程序的,给计算机看的。

定义:注解(Annotation),也叫元数据。一种代码级别的说明。它是JDK1.5及以后版本引入的一个特性,与类、接口、枚举是在同一个层次。它可以声明在包、类、字段、方法、局部变量、方法参数等的前面,用来对这些元素进行说明,注释。

特点:

  1. JDK1.5之后的新特性

  2. 说明程序的

  3. 使用注解: @注解的名称

2.注解的分类

2.1 编写文档

通过代码中的标识的注解,生成文档

复制代码
package com.keke.anno;

/**
 * 注解 JavaDoc 描述
 * @author keke
 * @version 1.0
 * @since jdk1.5
 */
public class AnnotationDemo01 {
    /**
     *  注解的描述
     * @param args
     */
    public static void main(String[] args) {

    }

    /**
     * 2个int类型的数据求和
     * @param a 第1个整数
     * @param b 第2个整数
     * @return
     * a+b的结果
     */
    public int add(int a, int b){
        return  a+b;
    }

    @Override
    public String toString() {
        return "AnnotationDemo01{}";
    }
}
View Code
复制代码

2.2 代码分析

通过代码里面的标识注解进行分析(反射)

 

2.3 编译检查

通过代码里面的标识的注解让编译器狗能实现基本的编译检查(Override)

 

二、JDK中预定义的注解

@Override

检测被该注解标注的方法是否是继承自父类(接口)的,如果是就编译通过,如果不是编译报错

 

@Deprecated

该注解标识的内容,表示已经过时了。

 

 

@SuppressWarnings

压制警告 一般传递参数 all 压制所有的警告

 

三、自定义注解

1.注解的格式

元注解
public @interface 注解名称{
属性列表;
}

2.注解中的属性列表

注解的本质其实就是一个接口,该接口继承自Annotation接口

2.1 注解的本质

创建第一个自定义注解

复制代码
package com.keke.anno;

public @interface MyAnnotation1 {

}
View Code
复制代码

 

通过反编译的文件可以看出我们自定义的注解本质上就是一个继承自Annotation接口的一个接口

2.2 属性列表

搞清楚了注解的本质,那么我就应该清楚在注解中我们能够写什么内容。

属性:注解中的方法我们称为属性

属性的返回值有哪些?

  1. 基本数据类型(包装类不行)

  2. String类型

  3. 枚举类型

  4. 注解

  5. 以上类型对应的数组

复制代码
package com.keke.anno;

/**
 * 自定义的 注解
 * 本质上是一个接口
 *     常量
 *     抽象方法
 */
public @interface MyAnnotation1 {
    String show();
    //不支持 void
    //void show2();
    //不支持自定义类型
    //PersonstudentUSER show3();
    //不支持包装类
    //Integer show5();
    MyAnnotation2 show6();

    PersonEnum show7();
    String[] show8();
    int[] show9();
    MyAnnotation2[] show10();
}
View Code
复制代码

属性的赋值

  1. 如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的复制

  2. 如果只有一个属性需要赋值(在注解中可以有多个属性,但是其他属性都有default默认值),并且属性的名称是value,则value可以省略,直接定义值即可

  3. 数组赋值时,值使用{}包裹,如果数组中只有一个元素,那么{}可以省略掉

复制代码
public @interface MyAnnotation2 {
    String show1();

    // default 给属性设置默认值,如果使用注解的时候没有指定对应的数值,就会用默认值来代替
    int age() default 18;

    String address();
}


public @interface MyAnnotation3 {
    String value();
    int age() default 18;
    String[] games();
}
View Code
复制代码
复制代码
package com.keke.anno;

import javax.swing.plaf.multi.MultiButtonUI;
import java.util.Date;

/**
 * 注解 JavaDoc 描述
 * @author keke
 * @version 1.0
 * @since jdk1.5
 */
public class AnnotationDemo01 {
    /**
     *  注解的描述
     * @param args
     */
    public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date.getDate());
    }

    @MyAnnotation3(value = "bbb",games = "LOL")
    public void fun1(){

    }

    @MyAnnotation3(value = "aaa",games = {"lol","cs","dnf"})
    public void ABC(){
        System.out.println("aaa");
    }

    /**
     * 2个int类型的数据求和
     * @param a 第1个整数
     * @param b 第2个整数
     * @return
     * a+b的结果
     */
    @SuppressWarnings("all")
    @MyAnnotation2(show1 = "keke",address = "南阳")
    public int add(int a, int b){
        return  a+b;
    }

    @Override
    public String toString() {
        return "AnnotationDemo01{}";
    }
}
View Code
复制代码

3.元注解

用于描述注解的注解我们称为元注解

3.1 @Target

描述注解能够作用的位置。

ElementType的取值:

TYPE:可以作用在类上

METHOD:可以作用在方法上

FIELD:可以作用在成员变量上

3.2 @Retention

描述注解被保留的阶段

RetentionPolicy.SOURCE:当前描述的注解保留到编码阶段

RetentionPolicy.CLASS:当前描述的注解保留到编译节点(class文件字节码中)

RetentionPolicy.RUNTIME:当前描述的注解保留到运行节点阶段,JVM会读取到。 我们自定义的注解 基本都是RUNTIME

3.3 @Documented

描述注解是否被抽取到api文档中

3.4 @Inherited

描述注解是否被子类继承

4. 自定义注解案例

实现一个自定义的注解,该注解作用在方法上,有被该注解标注的方法,在执行之前在控制台输出日志信息

复制代码
package com.keke.anno2;

import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
public @interface MyAnno1 {
    String value();
}
View Code
复制代码
复制代码
package com.keke.anno2;

import com.keke.anno.MyAnnotation2;

public class User {
    public void fun1(){
        System.out.println("fun1");
    }

    @MyAnno1("111")
    public void fun2(){
        System.out.println("fun2");
    }
}
View Code
复制代码
复制代码
package com.keke.anno2;

import com.keke.anno.MyAnnotation1;

import java.lang.reflect.Method;
import java.util.Date;

public class TestMain {
    /**
     *  实现一个自定义的注解,该注解作用在方法上,有被该注解标注的方法,在执行之前在控制台输出日志信息。
     * @param args
     */
    public static void main(String[] args) throws Exception{
        User user = new User();
        methodBefore(user,"fun1");
        user.fun1();
        methodBefore(user,"fun2");
        user.fun2();
    }

    private static void methodBefore(User user, String mehtodName)  throws Exception{
        Class<? extends User> aClass = user.getClass();
        Method declaredMethod = aClass.getDeclaredMethod(mehtodName);
        MyAnno1 annotation = declaredMethod.getAnnotation(MyAnno1.class);
        if(annotation!=null){
            System.out.println(annotation.value());
            System.out.println(declaredMethod.getName() + "在" + new Date() + "时执行了...");
        }

    }


}
View Code
复制代码

 

posted @   船长华莱士  阅读(32)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
点击右上角即可分享
微信分享提示