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); } }
反射
反射即反向探知,有点像考古学家根据发掘的物品来探知以前的事情
-
对于给定的一个类(Class)对象,可以获取到这个类(Class)对象的所有的属性和方法
-
对于给定的一个对象(new XXXClassName<? extends Object>),都能够调用它的任意一个属性和方法
这种动态获取类的内容以及动态调用对象的方法和属性的机制,就叫做Java的反射机制。
Java反射的优缺点:
优点:
-
增加程序的灵活性,避免将固有的逻辑程序写死在代码里面。
-
代码简洁,可读性增强,可提高代码的复用率
缺点:
-
相较于直接调用在量大的情况下反射性能下降厉害
-

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

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{}"; } }
通过代码里面的标识注解进行分析(反射)
2.3 编译检查
@Override
检测被该注解标注的方法是否是继承自父类(接口)的,如果是就编译通过,如果不是编译报错
@Deprecated
该注解标识的内容,表示已经过时了。
@SuppressWarnings
压制警告
元注解
public @interface 注解名称{
属性列表;
}
注解的本质其实就是一个接口,该接口继承自Annotation接口
2.1 注解的本质

package com.keke.anno; public @interface MyAnnotation1 { }
搞清楚了注解的本质,那么我就应该清楚在注解中我们能够写什么内容。
属性:注解中的方法我们称为属性
属性的返回值有哪些?
-
基本数据类型(包装类不行)
-
String类型
-
枚举类型
-
注解
-

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(); }
-
如果定义属性时,使用default关键字给属性默认初始化值,则使用注解时,可以不进行属性的复制
-
如果只有一个属性需要赋值(在注解中可以有多个属性,但是其他属性都有default默认值),并且属性的名称是value,则value可以省略,直接定义值即可
-

public @interface MyAnnotation2 { String show1(); // default 给属性设置默认值,如果使用注解的时候没有指定对应的数值,就会用默认值来代替 int age() default 18; String address(); } public @interface MyAnnotation3 { String value(); int age() default 18; String[] games(); }

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{}"; } }
用于描述注解的注解我们称为元注解
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

package com.keke.anno2; import java.lang.annotation.*; @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Documented @Inherited public @interface MyAnno1 { String value(); }

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"); } }

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() + "时执行了..."); } } }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)