代码审计-Java语法解析

-- 基础 --

特点

  • 强类型语言: 变量必须声明数据类型, 且变量的数据类型不可被改变
  • 赋值: java的赋值有返回值, 返回值即赋的值(等号右边的值)
  • 字符: 单引号代表单个字符, 而双引号代表一个字符串
  • 条件表达式: 判断语句只能接受布尔值, 连0和1都不能接收
  • 版本: JDK1.0 JDK1.1 JDK1.2 JDK1.5(Java5) Java6 Java7 Java8 Java11 Java17 Java21

源文件

  • 源文件与类: 文件中只能有一个 public 外部类(且该类的名称与文件要相同), 可以有多个非public外部类
  • 源文件程序开始: Java程序从包含 public static void main(String[] args) 方法的类开始执行
    注: main方法只能由public static修饰符修饰, 且返回值只能是void
  • 源文件编译: javac 文件名 编译后生成.class文件(数量为外部类+内部类的数量), 为 java 的字节码文件
    : 编译并不是只会生成public外部类的 类名.class 文件, 还会生成其它所有类的, 其中内部类为 外部类名$内部类名.class
  • 源文件执行: java 类的全限定名
  • 命令行参数:在命令行使用 java 命令执行Java程序时传入的参数, 会作为字符串数组传递给 main 方法的 String[] args 形参, 可以通过 args 数组来访问这些命令行参数

指令

javac <java源文件>
作用:编译.java文件(生成.class字节码文件)
   -d <目录> 指定生成.class文件的存放目录
   -cp <classpath> 指定编译时的(临时)类路径,若不指定该选项则会读取CLASSPATH环境变量
   -source <release> 指定源代码的版本
   -target <release> 指定生成的字节码的目标版本

java <类的全限定名> [args...]
作用:运行编译好的.class字节码文件(会启动一个JVM实例,并在该实例中加载并执行该类的main方法),args为传递给main方法的命令行参数
   -cp <classpath> 指定运行时的(临时)类路径,若不指定该选项则会读取CLASSPATH环境变量
   -D<系统属性>=<值> 更改运行时的系统属性(更改多个系统属性需要多个-D)
   -jar 运行可执行jar文件,类的全限定名 变为 jar文件路径

jar {c t x u}[f v m e 0 M i ][-C 目录]文件名...
作用:创建 查看 提取 Java归档文件(.jar文件)
   其中{ctxu}这四个参数必须选选其一 [v f m e 0 M i ]是可选参数 
   -c 创建一个jar包 
   -t 显示jar中的内容列表 
   -x 解压jar包 
   -u 添加文件到jar包中 
   -f 指定jar包的文件名 
   -v 生成详细的报告,并输出至标准设备 (控制台)
   -m 指定manifest.mf文件(manifest.mf文件中可以对jar包及其中的内容作一些一设置) 
   -0 产生jar包时不对其中的内容进行压缩处理 
   -M 不产生所有文件的清单文件(Manifest.mf),这个参数与忽略掉-m参数的设置 
   -i 为指定的jar文件创建索引文件 
   -C 表示转到相应的目录下执行jar命令,相当于cd到那个目录,然后不带-C执行jar命令

基础操作

  • 注释:单行 // 多行 /* */ 文档注释 /** */
  • 变量声明:
    <数据类型> <变量> [ = <值>][, <变量> [= <值>] ...] ;
    var <变量> = <值>(var声明会自动判断数据类型, >java 10)
  • 常量声明: final <数据类型> <变量> [ = <值>][, <变量> [= <值>] ...] ;
  • 类型转换: (数据类型)数据
    浮点数->整数 舍弃小数 而非四舍五入
    字符->数字 使用Unicode码对应数字
  • 自动类型转换:
    运算时不同类型数据先转化为同一类型, 然后进行运算(boolean 无法转换)
    byte,short,char—> int —> long—> float —> double (转换从低级到高级)
  • 循环:
while( 布尔表达式 ) {
//循环内容 
}
-- -- -- -- -- -- -- -- --
do {
       //代码语句
}while(布尔表达式);
-- -- -- -- -- -- -- -- --
for(初始化; 布尔表达式; 更新) {
}
-- -- -- -- -- -- -- -- --
>=java5
for(声明语句 : 表达式) { //类似于foreach 
//声明语句声明新的局部变量,该变量的类型必须和数组元素的类型匹配,其作用域限定在循环语句块,其值与此时数组元素的值相等
//表达式是要访问的数组名,或者是返回值为数组的方法
//代码句子 
}
-- -- -- -- -- -- -- -- --
break 跳出最里层的一层循环
continue 跳转到下一次循环
  • 条件语句
if(布尔表达式 1){ 
//如果布尔表达式 1的值为true执行代码 
}else if(布尔表达式 2){ 
//如果布尔表达式 2的值为true执行代码 
}else if(布尔表达式 3){
//如果布尔表达式 3的值为true执行代码 
}else { 
//如果以上布尔表达式都不为true执行代码 
}
-- -- -- -- -- -- -- -- --
switch(expression){ 
    case value : 
       // 语句 
       break; // 可选,若没有break,会执行后面的case语句
    case value : 
       // 语句 
       break; // 可选,若没有break,会执行后面的default语句
    default : // 可选 
       // 语句 
}
-- -- -- -- -- -- -- -- --
布尔表达式?表达式1:表达式2;

注:判断语句只能接受布尔值, 连0和1都不能接收

运算符

  • 算数运算符: 加+ 减- 乘* 除/ 取模% 及其 复合赋值运算符 += -= *= /= %=
  • 自增/自减运算符: ++x --x y++ y--
  • 关系运算符: 等于== 不等于!= 大于> 小于< 大于等于>= 小于等于<= (java没有强等于)
  • 逻辑运算符: 与 &&; 或 ||; 非 !
  • 位运算符: 与& 或| 异或^ 取反~ 左移<< 右移>> 无符号右移>>> 及其复合赋值运算符(略)
  • 三元运算符: 表达式1 ? 表达式2 : 表达式3
  • instanceof运算符
    使用: <对象> instanceof <类或接口>
    介绍: 若对象, 是操作符右侧类/接口自身或子类的一个实例, 那么返回true
    作用:

    1. 类型转换前检查数据类型, 以防报错(若转换成的数据类型 非 当前数据类型的子类, 则报错)
    2. 进行多态处理(根据对象类型执行不同逻辑)
    3. 泛型类型擦除后的补救
    4. 等等 使用规则:
    5. instanceof 不能用于基础数据类型(只能用于对应的 引用型类型)
    6. 如果 对象 是 null, 则直接返回false

基本数据类型

  • 基本数据类型: byte short int long float double boolean char
    byte: 8位, 有符号, 默认值为0 -128(-2^7) ->127(2^7-1)
    short: 16位, 有符号, 默认值为0 -32768(-2^15) -> 32767(2^15-1)
    int: 32位, 有符号, 默认值为0 -2^31 -> 2^31-1
    long: 64位, 有符号, 默认值为0L -2^63 -> 2^63-1
    float: 32位, 单精度, 默认值为0.0f
    double: 64位, 双精度, 默认值位0.0d boolean: 只有true和flase两个值, 默认值为false
    char: 储存单一16位Unicode字符, 默认值为 \'u0000\'
    注:字面量中整数的默认类型是int,小数默认是double
    注:要想字面量为long 值后面要加上l/L, float值后要加上f/F, double值后要加上d/D(可选)
    声明但未初始化的变量的值为默认值,声明但未初始化的数组的元素值为默认值
  • 引用类型: 对象 数组 (默认值为null)
  • 传递
    基本数据类型是值传递,
    引用类型变量传递的为本身的副本,但副本也指向同一个对象,本质也为值传递
    Java中其实还是值传递的,只不过对于对象参数,值的内容是对象的引用

变量

  • 变量: 局部变量 实例变量(非静态变量) 类变量(静态变量) 参数变量(即形参)
    局部变量: 在方法, 构造方法 或 语句块 中定义的变量

    • 在声明的方法、构造函数 或 块 执行结束后被销毁
    • 局部变量在声明后需要初始化后才能使用,否则会导致编译错误

    实例变量: 声明在类中, 方法、构造函数 或 块之外的变量

    • 在创建对象的时候实例化, 实例变量值不共享, 可被类中方法、构造方法 和 特定类的语句块 访问
    • 可不初始化就使用, 会被赋予相关数据类型的默认值

    类变量: 类变量也声明在类中,方法、构造函数 或 块之外,但必须声明为 static 类型

    • 同一个类的所有实例共享同一个类变量的值, 可被类中方法、构造方法 和 特定类的语句块 访问
    • 可不初始化就使用, 会被赋予相关数据类型的默认值

修饰符

  • 访问修饰符(从严到松):
    private : 在同一类内可见 使用对象:字段、方法、内部类(外部类不可用)
    default(即什么也不写): 对同一包内的类可见 使用对象:类、接口、字段、方法
    protected : 对同一包内的类 和 所在类的所有子类(包括不同包的)可见 使用对象:字段、方法、内部类(外部类不可用)
    public : 对所有类可见 使用对象:类、接口、字段、方法
  • final关键字
    可使用对象:变量(包括类属性、对象属性、局部变量和形参),方法(包括类方法和对象方法)和类
    修饰类:类不能被继承
    修饰方法:方法不能被子类重写
    修饰变量:定义常量
  • static关键字
    可使用对象:类属性 类方法 代码块 import导入 内部类
    修饰类属性(静态变量):使属性属于类,可通过类名直接访问,该类创建的所有实例共享该变量的值
    修饰方法(静态方法):可通过类名直接访问,在静态方法中只能访问静态成员,且无法使用this关键字,直接用对应名称即可(可以通过实例来访问静态方法,但不推荐)
    修饰代码块(静态代码块):用于初始化静态变量,在类首次被加载时执行一次(如第一次调用类的静态方法或静态变量之前 或 第一次创建类的实例之前), 且无法使用this关键字,直接用对应名称即可
    修饰import:可导入特定/全部的静态成员
    修饰内部类:使内部类可以访问外部类的静态变量与静态方法

类与对象

  • 创建类: [修饰符] class 类名{}
  • 继承:
    [修饰符] class 类名 extends 要继承的类名{}
    [修饰符] class 类名 implements 接口,... { }
    作用: 继承父类非private的属性和方法 (静态字段/方法也会继承, 但子类静态字段与父类的指向不同)
    多继承: 不支持多继承, 一次只能继承一个类(用extends), 但可做到多继承接口(用implements)
    构造方法: 不会继承父类的构造方法
    特点: 所有的类都是继承于 java.lang.Object,当一个类没有继承的两个关键字,则默认继承 Object
  • 构造方法
    定义: 必须与类同名, 不用写返回值类型(因为没有返回值)
    特点: 创建对象时,若没有显式地定义构造方法,编译器将会为该类提供一个默认的构造方法
    构造方法链: 可在构造方法中用this(参数)来调用其它构造方法, 使得创建对象时使用多个构造方法
  • 方法重载: 同一个类中可设定多个同名方法, 但形参列表不同(数据类型 顺序或数量不同), 访问方法时会根据传入的实参(数据类型 顺序或数量)来自动判断运用哪个方法(类的方法也可在子类中被重载)
  • 方法重写: 在方法前一行加上@Override(可不加),子类中可重新定义继承自父类的同名方法
    条件:
    方法名相同 参数列表相同 返回类型必须相同或为父类返回类型的子类型(<=java5) 返回值可以不同(>=java7)
    访问修饰符不能比父类方法更严格 不能抛出比父类方法更广泛的检查异常
    final方法不能被重写,static方法无法被重写但能被再次声明
    无法重写构造方法(因为不会继承构造方法)
  • 父类引用指向子类对象: 父类名 变量1 = new 子类();
    特点: java 中可以用 父类 引用指向 子类对象, 也可以指向子类的子类 ...
    特点:使得 可以通过该引用 访问 子类从父类继承的 成员变量 与 方法, 而不能访问子类特有的 成员变量 与 方法
    特点: 对于被子类重写后的方法, 通过该引用 访问的是 重写后的方法
    特点: 可通过 子类名 变量2 = (子类名)变量1; 来再将类型变回子类引用
  • this关键字: 代表当前对象自身
    调用所在类的字段与方法(在方法体中): this.字段this.方法(...)此时可省略this, 当形参与成员名重名时才需加上this以区分
    调用所在类的其它构造方法(在构造方法体中): this(...)应为所在构造函数的第一条语句
    返回当前对象(实现链式调用): return this
  • super关键字: 代表当前对象的父类实例部分
    调用从父类继承的非private字段与方法(在方法体中): super.字段super.方法(...)
    此时可省略super, 当子类字段与父类字段重名时 或 父类方法被子类重写时 才需加上super以区分
    子类中调用的父类的方法时 其中的 字段/方法()this.字段/方法()super.字段/方法 与在子类中使用 相同内容 的效果相同
    调用父类的构造函数(在构造方法体中): super(...)
    子类中调用的父类的方法时 其中的 字段/方法()this.字段/方法()super.字段/方法 与在子类中使用效果相同
    应为所在构造函数的第一条语句
    调用子类构造函数时, 若检测到没用 super(...) 调用父类构造方法, 系统会自动调用父类的无参数构造方法(相当于在第一行加上 super())
  • 实例化: 类名 变量 = new 类名(形参)
    创建实例数组: 类名[] 变量 = new 类名[] {实例,...}
  • 访问实例: 实例变量.成员
  • 抽象类/方法: 通过在类/方法的定义前(修饰符后)加上 abstract 关键词以声明
    抽象类特点: 抽象类 不能用 new 创建对象(实例化), 必须被继承, 才能被使用
    抽象类的方法: 抽象类 中可以有 构造方法 正常方法 与 抽象方法
    抽象方法特点: 抽象方法不包含方法体(即没有花括号即其内的内容), 且只能存在于 抽象类中, 构造方法 与 类方法 不能声明为 抽象方法
    抽象方法的实现: 抽象方法所在抽象类的子类 必须为 抽象类 或 重写了所有从 父类继承来的抽象方法(抽象方法的实现)
  • 代码块:
    普通: 在类中没有任何修饰的代码块, 其内容会在实例化时执行(并且先于构造函数执行)
    静态代码块: 在类被第一次加载时执行(如第一次调用类的静态方法或静态变量之前 或 第一次创建类的实例之前)
  • 内部类与外部类:
    概念: 在类中定义的类, 叫内部类, 而包含该内部类的类叫外部类
    特点: 内部类可以使用外部类的成员变量(包括私有)
  • 多态: 概念, 同一个接口, 使用不同的实例而执行不同操作(功能), 常用 继承 重写 父类引用指向子类对象 接口 抽象类/方法 来实现
  • 封装: 概念, 将对象的 成员变量 私有化(private), 在对象外部通过公共(public)方法访问 这些成员变量
  • 单例模式: 概念, 将构造方法设置为私有的, 在私有静态属性N中储存实例, 利用静态方法返回该静态属性(若N为空则创建实例存储在N中)
    作用: 保证了从头到尾只有一个实例, 对于全局只想进行一次并维持结果(因为类属性不会像对象一样被销毁)的操作 可利用单例模式

方法

  • 定义: [修饰符] 返回值类型 方法名(参数数据类型 形参名){方法体}
    [修饰符] abstract 返回值类型 方法名(参数数据类型 形参名) (抽象方法)
    返回值类型写 void 表示无返回值, 返回值在函数体中用return返回
  • 特点: Java函数的变量无法设置默认值, 只能通过重载来实现类似默认值的效果
  • 可变参数(JDK>=1.5): 在指定参数类型后加一个省略号(...)
    限制: 一个方法中只能指定一个可变参数,且它必须是方法的最后一个参数
    特点: 可变参数意味着调用该方法时可传入符合数据类型 零个或多个实参, 而形参会变为储存所有实参值的数组

接口

  • 声明: [修饰符] interface 接口名{接口体}
  • 特点:
    接口与抽象类 类似, 接口内也能定义方法, 接口是抽象的, 不能实例化对象, 并且也没有构造方法
    接口是 隐式 抽象的, 无需使用 abstract 关键字
    接口没有构造函数
  • 方法:
    接口内的方法 都会被 隐式地 指定为 public abstract
    不能显示地指定 public abstract 以外的方法
    所以重写接口方法不能使用除public以外修饰符(java<8)
    java>8 后, 可以使用 default 显式地定义非抽象的方法
  • 成员变量(字段):
    接口内的变量 都会被 隐式地 指定为 public static final
    不能显示地指定 public static final 以外的变量
    所以接口的成员变量一般被定义为常量, 或用于存储配置信息
  • 接口的实现:
    接口由类来实现, 类通过 implements 关键字继承的方式来实现接口
    类实现接口时, 必须实现接口中的所有方法 或者 声明为抽象类
  • 继承: [修饰符] interface 接口名 [extends 其它接口名,...]{接口体}
    接口可以同时继承多个接口 (接口继承接口用 extends, 类实现接口用 implements)
  • 特点
    类在实现接口的方法时, 不能抛出强制性异常, 只能在接口中, 或者继承接口的抽象类中抛出该强制性异常
    实现类可以抛出异常, 但不能抛出比接口方法声明的异常更宽泛的受检查异常
    一个类可以同时实现多个接口, 但只能继承一个类

包装类

  • 作用: 为方便, 有时我们需要使用对象, 而不是内置数据类型, 而Java 语言为每一个内置数据类型提供了对应的包装类(引用型类型), 使得可以将基础数据类型的值转化为对象
  • 使用(装箱): 将基础数据类型的值转化为对象
    包装类 变量 = new 包装类(基本数据类型的值) 基础操作
    var 变量 = new 包装类(基本数据类型的值) 会自动判断数据类型
    包装类 变量 = 基本数据类型的值 会自动转化为对象
  • 使用(拆箱): 将对象转化为基础数据类型的值
    基础数据类型 变量 = 对象 基础操作
包装类 与对应 基础数据类型
Byte-byte   Short-short  Integer-int  Long-long  
Float-float  Double-double  Boolean-boolean  Character-char
  • 包装类 Integer Long Byte Double Float Short 是抽象类 Number 的子类, Number 类属于 java.lang 包
  • Number类及子类使用方法是直接 类.方法() 无需加入参数, 而Math类使用方法是 Math.方法(数值)

  • 包名(全限定名): 包名通常使用小写字母, 并使用点号分隔, 包名通常与目录结构对应(包括内部包和外部包)
  • package 语句: 声明类所在的包, 若使用, 它应该是 Java 源文件中的第一个语句(除了注释)
    package 包名; 添加到包中 (注: 该行语句同时带有类似于 import 包名.*; 的效果)
  • import 语句: 导入其他包中的类, 使得可以在当前文件中使用这些类而不需要写出它们的完全限定名
    import 包名.类名,...; 导入类 import 包名.*; 导入所有类
    import 语句应该放在 package 和类定义之间, 若没有 package, 则import 应该在最前面
    注: 只能引入编译后的 .class 文件
  • 系统包
    java.lang - 基础的类(只有java.lang包会自动引入)
    java.io - 包含输入输出功能的函数
  • 路径: 类目录的绝对路径叫做 class path, 设置在系统变量CLASSPATH中
    编译器和 java 虚拟机通过将 package 名字加到 class path 后来构造 .class 文件的路径
    注: 若无CLASSPATH系统变量, 则默认为.和JDK的lib路径
  • 注意: import和package对源文件中定义的所有类都有效, 同一源文件中,不能给不同的类不同的包声明

泛型

  • 概念: 相当于参数化类型, 即为将数据类型当作一个参数
    注: 泛型只能代表 引用数据类型, 而不能代表基础数据类型(得用对应的包装类)
  • 泛型格式: <泛型标记符 [上/下通配符]>
  • 泛型标记符(约定命名):
    E - Element 集合
    T - Type Java类
    K - Key 键
    V - Value 值
    N - Number 数值类型
    ? - 不确定的类型
  • 通配符
    上界通配符: extends 类/接口/标记符T 表示泛型类型是 T 或 其子类 (只能读, 不能写)
    下界通配符: super 类/接口/标记符T 表示泛型类型是 T 或 其父类 (只能写, 读时只能当作Object)
  • 泛型方法声明: [修饰符] <泛型,...> 返回值类型 方法名(参数数据类型 形参名){方法体}
    泛型类声明: [修饰符] class 类名<泛型,...> {类体}
    使用: 声明后即可在 返回值类型 参数数据类型 和 方法体 / 类的字段 与 方法 中使用
    使用范围: 泛型类定义的泛型是 供给实例来使用的, 所以泛型类定义的泛型 不能在静态字段与静态方法中使用, 但静态方法可以定义为泛型方法, 从而使用自己定义的泛型 而非 类定义的泛型
    声明: 若类声明了, 则其中的方法无需再声明
    : 若声明多个泛型, 则用逗号隔开, 但标记符名字不能相同
  • 引用泛型方法: 与引用普通方法相同, 系统会自动判断传入的数据类型
    引用泛型类:
    创建实例: 类名<具体数据类型> 变量名 = new 类名<具体数据类型>(...)
    创建实例(>java7可用): 类名<具体数据类型> 变量名 = new 类名<>(...)
    : 类名<?>相当于类名<具体数据类型>的父类, 具体数据类型不能是基础数据类型, 要使用对应的引用数据类型
    使用静态字段/方法: 直接使用 类名.字段/方法

系统属性

  • 介绍: 用于存储JVM运行环境相关信息, 会影响Java程序行为(类似于系统配置)
  • 更改方式:
    1. 代码中 System.setProperty(String key, String value) 方法设置
    2. 用java指令运行时, 使用 -D 选项设置

枚举

  • 简介: 用来表示一组常量, 枚举类本质是一种特殊的类(继承了java.lang.Enum的类)
    其中的枚举常量相当于其实例,
    由于是类, 所以可以定义在内部类中, 其内也可定义类与方法
  • 定义
// 定义
[修饰符] enum Color 
{ 
    RED, GREEN, BLUE; 
} 

// 赋值
Color test = Color.RED // 注:此时该变量会被隐式定义为 public static final, 作为枚举类的常量

switch(test){
    case RED: // 在case语句中,类似Color.RED等可以直接简写为RED
        break;
    case GREEN:
        break;
    case BLUE:
        break;
}

注解Annotation

  • 简介: 写给程序看的注释, 用于传递元数据, 类 方法 变量 等多种元素都可被标注, 且能通过反射获取标注内容
    注: 注解都继承自java.lang.annotation.Annotation
  • annotation包定义:
package java.lang.annotation;
public interface Annotation {
    boolean equals(Object obj);
    int hashCode();
    String toString();
    Class<? extends Annotation> annotationType();
}
public enum ElementType {  
    TYPE,               /* 用于类、接口(包括注释类型)或枚举声明  */  
    FIELD,              /* 用于字段声明(包括枚举常量)  */  
    METHOD,             /* 用于方法声明  */  
    PARAMETER,          /* 用于参数声明  */  
    CONSTRUCTOR,        /* 用于构造方法声明  */  
    LOCAL_VARIABLE,     /* 用于局部变量声明  */  
    ANNOTATION_TYPE,    /* 用于注释类型声明  */   
    PACKAGE             /* 用于包声明  */  
}
public enum RetentionPolicy {  
    SOURCE,            /* 注解仅存在于源代码中,编译时会被编译器丢弃,运行时不可见,用于定义标记注解 */
    CLASS,             /* 注解会被保留到.class文件中,但JVM在运行时不会加载注解信息,无法通过反射访问,默认行为 */
    RUNTIME            /* 注解不仅存在于.class文件中,JVM加载类后仍可通过反射获取 */  
}
  • 标记注解(没有成员变量的注解, 仅起到标记作用)
    @Override - 检查该方法是否是重写方法, 如果发现其父类, 或者是引用的接口中并没有该方法时, 会报编译错误
    @SafeVarargs (>=java7) - 忽略任何使用参数为泛型变量的方法或构造函数调用产生的警告
    @FunctionalInterface (>=java8) - 标识一个匿名函数或函数式接口
  • 功能型注解(通过定义特定成员变量, 为编译器或工具提供具体行为指令的注解)
    @Deprecated - 标记过时方法, 如果使用该方法, 会报编译警告
    @SuppressWarnings - 指示编译器去忽略注解中声明的警告
  • 元注解(作用于其它注解的注解):
    @Target(ElementType type[])@Target(ElementType type) - 标记这个注解应该用于哪(见ElementType定义, 默认用于所有)
    @Retention(RetentionPolicy policy) - 标识这个注解怎么保存与生命周期(见RetentionPolicy定义, 默认为RetentionPolicy.CLASS)
    @Inherited - 标记这个注解在用于类声明时, 会被该类的子类继承 (默认 注解不会继承给子类)
    @Documented - 标记这些注解是否包含在用户文档中 (待定)
    @Repeatable (>=java8) - 标识某注解可以在同一个声明上使用多次 (待定)
  • 自定义注解
[修饰符] @interface <注解名> {
    <数据类型> <成员名>() [default <默认值>]; 
    // 数据类型只支持 基本数据类型/String/Class/enum/其它注解 及这些类型的数组
    ...
}

使用注解时,实参会赋值给成员,然后通过反射取出来执行相关逻辑

JavaBean

  • Bean: JavaBean是特殊的Java类, 遵守JavaBean API规范
  • 条件
    需为公共类, 需拥有一个无参构造函数
    需可序列化(实现Serializable接口)
    所有属性需为私有属性(假设属性名为test), 若想读取属性, 需定义getTest()方法来读; 若想写入, 需用setTest()方法来写
    (属性可只读/只写, 只定义getTes()为只读, 只定义setTest()为只写)
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇