Java语言基础二(类和对象, 方法和封装, static 关键字和继承, 多态和特殊类)

面向对象 -- 指以属性和行为的观点区分析现实生活中的事物。
面向对象编程 -- 指以面向对象的思想进行分析,然后使用面向对象的编程语言进行表达的过程,是软件产业化发展的需求。

理解面向对象的思想 (封装, 继承, 多态)。

C: 面向过程语言
C++: 面向过程和面向对象语言
Java: 面向对象语言

类和对象

对象主要指现实生活中客观存在的实体。在 Java 语言中对象体现为内存空间中的一块存储区域。类是对具有相同特征和行为的多个对象共性的抽象描述。在 Java 语言中体现为一种引用数据类型。

描述特征/属性 -> 成员变量

描述行为 -> 成员方法

类用于构建对象的模板, 对象的数据结构由定义它的类来决定

类的定义

class 类名{

      数据类型  成员变量  =  初始值;

       //  成员方法;
      返回值类型  成员方法名 (形参列表){
               成员方法体;
      }
        

}

命名规范:

类名 -- 多个单词组成时, 要求每个单词首字母都要大写

成员变量 -- 多个单词时, 第二个单词起每个单词的首字母大写

成员方法 -- 多个单词时, 第二个单词起每个单词的首字母大写

引用变量 -- 多个单词时, 第二个单词起每个单词的首字母大写

成员变量的初始值:

基本数值类型 -> 0

boolean 类型 -> false

引用类型 -> null

成员方法: -- 可以实现代码的重用, 简化代码

返回值:指从方法体内返回到方法体外的数据内容

形参列表:将方法体外的数据内容带入到方法体内

方法体:主要用于编写描述该方法功能的语句块

注:普通类不允许被声明为 static 和 private,只有内部类才可以。

对象的创建:

本质就是在内存空间的堆区中申请一块存储区域,用于存放该对象的独有特征信息。
使用 new 关键字来创建该类的对象, 这个过程叫做类的实例化;

 MyClassName myName = new MyClassName();   //使用 new 关键字来创建该类的对象, 这个过程叫做类的实例化;
引用的定义

使用引用数据类型定义的变量叫做引用型变量, 简称"引用";
引用变量主要用于记录对象在堆区中的内存地址信息。

语法格式:

类名 引用变量名 = new 类名();

引用变量名.成员变量名 = value;

如:
Person  p  =  new  Person();
p.name = "zhangsan";
System.out.println(p.name);
底层内存结构

可以给引用类型赋值为 null, 表示不指向任何对象。

Person p = null;

此时如果通过引用访问成员变量或调用方法, 会产生空指针异常。

传参

参数分为形参实参

  • 形参 -- 定义方法时的参数

  • 实参 -- 调用方法时传递的参数

调用方法时采用值传递把实参传递给形参,方法内部其实在使用形参。
当参数是对象时, 传递的是对象的地址值,对象的值为对象的地址。

可变长参数:

返回值类型 方法名(参数的类型... 参数名){};

方法参数部分指定类型的参数个数是可以改变的, 为 0 ~ n;
一个方法的形参列表最多只能声明一个可变长形参,并且需要放到参数列表的末尾。

参数传递时的注意事项
  • 基本数据类型的变量作为方法的参数传递时,形参变量的数值改变通常不会影响到实参变量,因为两个变量有各自独立的内存空间。
  • 引用数据类型的变量作为方法的参数传递时,改变形参变量指向内容会影响到实参变量,因为两个变量指向同一块内存空间。
  • 引用数据类型的变量作为方法的参数传递时,若形参变量改变指向后再改变指定内容,通常不会影响到实参变量指向内容的改变,因为两个变量指向不同的内存空间。
内存结构之栈区

栈用于存放程序运行过程当中所有的局部变量。
一个运行的 Java 程序从开始到结束会有多次方法的调用,JVM 会为每个方法的调用分配一个对应的空间,该空间为该方法的栈帧, 对应一个调用中的方法,栈帧存储了该方法的参数, 局部变量等数据。当某一个方法调用完成后,其对应的栈帧将被清除。


方法和封装

递归与递推

递归

从最终态向前递推, 然后不断回溯,在方法体内部直接或间接调用当前方法自身的形式。

注意事项:

  • 必须有递归的规律以及退出条件
  • 必须使得问题简单化而不是复杂化
  • 若递归影响到程序的执行性能, 则使用递推取代之
递推

正向递推 :从初始态出发, 不断改变自己;
反向递推:与正向逻辑相反, 类似递归。

迭代

重复反馈过程的活动,目的是去逼近所需目标或结果。

案例:实现累乘积(阶乘)的计算

public class JieChenTest{

     
     int show(int n){

          // 递 推 方 式:
          int num = 1;
          for(int i = 1; i <=n; i++){
          num += i;
          }  

        // 递 归 方 式:
         if(1 == n){                   //当n的数值为1时,阶乘的结果就是1
            return 1;
         } 
         return n*show(n-1);    //否则就是阶乘的结果为 n*(n1)
     
     }
   
     

    public static void main(String[] args){
        JieChenTest jct = new JieChenTest();
        int res = jct.show(5);
        System.out.println("最后计算结果为:" + res)    //120        
           
    }
}

构造方法

概念:

构造方法名与类名完全相同并且没有返回值类型;
当类中没有定义任何构造方法, 使用默认构造方法, 编译器会自动添加一个无参空构造方法: 如 Person() {}

作用:

使用 new 关键字创建对象时会自动调用构造方法,实现成员变量初始化工作。

格式:

class MyClassName {
 
         MyClassName(参数列表) {
 
             构造方法体;
 
         }
 
}

方法重载(Overload)

概念:

多个方法的方法名相同, 参数列表不同。这样的方法之间构成重载关系。

体现形式:
  • 参数的个数不同、参数的类型不同、参数的顺序不同,与返回值类型和形参变量名无关,建议返回值类型最好相同。

  • 判断方法能否构成重载的核心:调用方法时能否加以区分

实际意义:

调用者只需记住一个方法名就可以;
调用各种不同的版本,实现各种不同的功能

this 关键字

-- 本质上就是当前类类型的引用变量
-- 可以通过 "this." 的方式调用成员变量和成员方法

基本概念:

若在构造方法中出现, 则代表当前正在构造的对象
若在成员方法中出现, 则代表当前正在调用的对象

工作原理:

在构造方法中和成员方法中访问成员变量时,编译器会自动加上 this.的前缀。当不同对象调用同一个方法时,调用对象不同导致 this 不同,从而 this.方式 访问的结果也不同

使用方式:
  • 在构造方法的第一行可以使用 this() 的方法,调用本类的其他构造方法;
  • 当局部变量名与成员变量名相同时, 在方法中会优先使用局部变量(就近原则);
  • 若希望使用成员变量,则在成员变量前加上 this 前缀, 明确要求该变量是成员变量;
  • this 关键字还可以作为方法的返回值。

封装

概念:

隐藏成员变量的细节以及保证成员变量数值的合理性;
对成员变量进行密封包装处理,避免出现与现实不符合的数值。

实现流程:
  • 私有化成员变量, 使用 private 关键字修饰;
  • 提供公有的 get 和 set 方法;
  • 在方法中进行合理值的判断;
  • 在构造方法中调用 set 方法进行合理值判断;

注:成员变量和方法什么修饰符都没有叫做默认访问权限,级别介于 private 和 public 之间。

JavaBean

-- 一种 Java 语言写的可重用组件,
-- 其它 Java 类可以通过反射机制来发现和操作这些 JavaBean 的属性。

本质上是符合以下标准的 Java 类

  • 类是公共的;
  • 有一个无参的公共的构造器;
  • 有属性,且有对应的 get, set 方法。

static 关键字和继承

static 关键字

概念:
  • 使用 static 修饰成员变量表示静态的含义,
  • 此时成员变量由对象层级升级为类层级,整个类只有一份并被所有对象共享;
  • 该成员变量随着类的加载准备就绪,与是否创建对象无关
  • static 修饰的成员可以使用"引用."的方式访问, 但推荐"类名."的方式;
  • static 修饰内部类可以直接作为一个普通类来使用。
使用方式
  • 在非静态成员方法中: 既能访问非静态成员又能访问静态成员,因为静态成员被所有对象共享;
  • 在静态成员方法中:不能使用 this 和 super 关键字;只能访问静态成员不能访问非静态成员,因为此时对象可能还未被创建;
  • 不能滥用 static 关键字:开发中只有隶属类层级,并被所有对象共享的内容,才可以使用 static 关键字修饰。

静态成员变量:构造方法不再初始化静态成员变量,用静态成员方法访问静态成员变量。

final 关键字

-- 可以修饰类, 成员方法以及成员变量

使用方式:
  • 修饰类体现在该类不能被继承,主要用于防止滥用继承,如 java.lang.String。
  • 修饰成员方法体现在该方法不能被重写但可以被继承,主要防止不经意间造成重写,如 java.text.Dateformat 类中 format 方法。
  • 修饰成员变量体现在该变量必须初始化且不能改变,主要防止不经意间造成改变,如 java.lang.Thread 类中 MAX_PRIORITY。
常量

通常使用 public static final 关键字共同修饰成员变量
命名规范:要求所有字母都要大写, 不同单词之间采用下划线连接

public static final double PI_CONSTANT = 3.14159

构造块和静态代码块

构造块:
  • 在类体中直接使用 {} 括起来的代码块;
  • 每创建一个对象都会执行一次构造块;
  • 在 super() 后和目前对象构造方法前执行;
  • 可以使用 this 访问成员;
  • 用来初始化非静态成员变量;
  • 可以执行非静态成员方法;
静态代码块:
  • 使用 static 关键字修饰的构造块
  • 随着类加载时执行一次
  • 在构造块之前执行
  • 不可以使用 this 和 super 关键字
  • 用来初始化静态成员变量,
  • 可以执行静态方法

构造块和静态代码块执行顺序:

1. 执行父类的静态代码块, 执行子类的静态代码块
2. 执行父类的构造块, 执行父类的构造方法体
3. 执行子类的构造块, 执行子类的构造方法体

单例类 -- Singleton

对外提供且只提供一个对象
单例设计模式 -- 设计单例类的流程和思想
三要素:

  • 私有化构造方法,使用 private 关键字修饰
  • 指向自己实例的私有静态引用, 使用 private static 关键字共同修饰
  • 以自己实例为返回值的静态的公有方法,使用 public static 关键字共同修饰

类图:

1. 类图分三部分,
依次为 "类名, 属性, 方法";
2. 以 << 开头和以 >> 结尾的为注释;
3. 修饰符 + 代表 public, - 代表 private,
'#' 代表 protected,什么都没有代表包可见;
4. 带下划线的属性或方法代表是静态的

实现方式:

饿汉模式 (立即加载, 线程安全, 推荐):类加载慢, 运行时获取对象快

/*
   饿汉式
 */
public class Singleton {
     // 2. 使用private static 共同修饰对象的引用
    private static Singleton sin = new Singleton();

     //1. 私有化构 方法 使用private关键字修饰
    private Singleton(){ }

   // 3.  提供公有的get方法将对象返回出去,用public static共同修饰
    public static Singleton getInstance(){
        return sin;
    }

}

懒汉模式 (延迟加载, 非线程安全):类加载快, 运行时获取对象慢

/*
   懒汉式
 */

public class Singleton {

    // 2.声明本类类型的引用指向本类类型的对象并使用private static关键字修饰
    private static Singleton sin = null;

    // 1.私有化构造方法,使用private关键字修饰
    private Singleton() {}

    // 3.提供公有的get方法负责将上述对象返回出去,使用public static关键字修饰
    public static Singleton getInstance() {
      
        if (null == sin) {
            synchronized (Singleton.class) {
                if (null == sin) {
                    sin = new Singleton();
                }
            }
        }
        return sin;
    }
}

注:多线程环境下:使用双重检验,保证单例提高运行效率,必须使用 volatile,使用私有静态内部类,实现延迟加载和线程安全;在同一个类加载器下,一个类只会被初始化一次

继承

概念

当多个类之间有相同的特征和行为时,可以将相同的内容提取出来组成一个公共类,让多个类吸收公共类中已有特征和行为而在多个类型只需要编写自己独有特征和行为的机制,叫做继承

例如:
public class Worker extends Person{}

// Person 类叫超类, 父类, 基类
// Worker 类叫派生类, 子类, 孩子类

使用继承提高了代码复用性, 可维护性及扩展性,是多态的前提条件。

继承特点:
  • 子类不能继承父类的构造方法和私有方法,但私有成员变量可以被继承, 只是不能访问;
  • 无论使用何种方式构造子类的对象,都会自动调用父类的无参构造方法,来初始化从父类继承的成员变量,相当于在构造方法第一行写 super();
  • 使用继承必须满足"子类 is a 父类"逻辑关系,不能滥用继承;
  • Java 只支持单继承不支持多继承:一个子类只有一个父类,但一个父类可以有多个子类。
方法重写 -- Override

从父类中继承下来的方法不满足子类的需求时,就需要在子类中重新写一个和父类一样的方法来覆盖从父类中继承下来的版本,该方式就叫做方法的重写(Override)。

注意:加"@Override"注解, 若没有构成重写则编译报错

方法重写的原则:

  • 要求方法名相同, 参数列表相同以及返回值类型相同,从 Java 5 开始允许返回子类类型;
  • 要求方法的访问权限不能变小, 可以相同或变大
  • 要求方法不能抛出更大的异常 (异常机制)

访问控制符

访问控制符

注意事项:

  • public 修饰的成员可以在任意位置使用,
  • private 修饰的成员只能在本类内部使用,
  • 通常, 成员方法使用 public 关键字修饰,成员变量使用 private 关键字修饰。
包语句 -- package

-- 使用包的概念:实现项目管理, 解决命名冲突以及权限控制的效果。
定义一个类时, 除了定义类的名称一般还要指定一个包名
package 包名;
package 包名1.包名2.包名3...包名n;

-- 定义包的规范:org.apache.commons.lang.StringUtil
其中 :
         类名: StringUtil
         模块名称信息: lang -------------\
         项目名称信息: commons ------------> 多层包名
         公司或组织的信息: org.apache ----/

-- 包的导入:

  • 使用 import 关键字导入包
  • 使用 import 关键字导入静态成员,
  • 从 Java 5.0 开始支持
  • import static java.lang.System.out

多态和特殊类

多态

-- 同一种事物表现出来的多种形态。 比如, 人表现为学生, 教师, 工人, 保安...

语法格式:

父类类型 引用变量名 = new 子类类型();
ParentClass p = new ChildClass();

多态特点:
  • 当父类类型引用指向子类类型的对象时:
    父类类型的引用可以直接调用父类独有的方法,不可以直接调用子类独有的方法;

  • 对于父子类都有的非静态方法来说:
    编译阶段调用父类版本,运行阶段调用子类重写的版本 (动态绑定);

  • 对于父子类都有的静态方法来说:
    编译和运行阶段都调用父类版本。

多态的实际意义

屏蔽不同子类的差异性实现通用的编程带来不同的效果.。

多态使用场合

  1. 通过方法的参数传递形成多态;
    public static void draw(Shape s){
    s.show();
    }
    draw(new Rect(1, 2, 3, 4));

  2. 在方法体中直接使用多态的语法格式;
    Account acc = new FixedAccount();

  3. 通过方法的返回值类型形成多态
    Calender getInstance(){
    return new GregorianCalendar(zone, aLocale);
    }

推荐使用多态的格式,此时父类类型引用直接调用的方法一定时父类拥有的方法,以后更换子类时, 只需修改 new 关键字后面的子类类型,而其它地方无需修改就可以立即生效,提高了代码的可维护性和可扩展性。

缺点:父类引用不能直接调用子类独有的方法,若调用则需要强制类型转换。

引用数据类型之间的转换:
  • 必须发生在父子类之间, 否则编译报错
  • 自动类型转换:小类型向大类型的转换。即:子类转为父类, 叫做向上转型或隐式类型转换。
  • 强制类型转换:大类型向小类型的转换。即:父类转为子类, 叫做向下转型或显式类型转换。
  • 若强转的目标类型并不是该引用真正指向的数据类型则编译通过, 运行阶段发生类型转换异常。
  • 应该在强转前进行判断, 格式如下:
    if (引用变量 instanceof 数据类型)
    判断引用变量指向对象是否为后面的数据类型

抽象类

抽象方法

抽象方法主要指不能具体实现的方法并且使用abstract关键字修饰,也就是没有方法体。

-- 具体格式如下:

访问权限 abstract 返回值类型 方法名(形参列表);
public abstract void cry();

注意:以下关键字 和 abstract 关键字不能共同修饰一个方法:private,final,static。

抽象类

抽象类主要指不能具体实例化的类并且使用abstract关键字修饰,也就是不能创建对象。
如:public abstract class Account {}

意义:

  • final 关键字不能修饰抽象类;
  • 当一个类继承抽象类后必须重写抽象方法,否则该类也变成抽象类。抽象类对子类具有强制性和规范性,因此叫做模板设计模式;
  • 实际意义:不在于创建对象而在于被继承

抽象类和抽象方法的关系:

  • 抽象类可以有成员变量, 构造方法, 成员方法;
  • 抽象类可以没有抽象方法, 也可以有抽象方法;
  • 拥有抽象方法的类必须是抽象类;
  • 真正意义上的抽象类:具有抽象方法并且使用 abstract 关键字修饰的类。

接口

-- 一种比抽象类还抽象的类, 所有方法都为抽象类。
-- 定义类的关键字是class,而定义接口的关键字是interface。

注意:

  1. 接口内部只能有常量: 默认为 public static final
    /*public static final*/ int CNT = 1;

  2. 接口内部只能有抽象方法, Java 新特性除外
    /*public abstract*/ void show();

  3. Java 8 新特性允许默认方法和静态方法
    默认方法可以选择重写与否, default 关键字修饰;
    静态方法不可以被重写

  4. Java 9 新特性允许接口中出现私有方法
    同样的, interface 的私有方法也不可以为 abstract;
    private 不可以修饰 default,因为 default 可能会被实现类重写;
    将私有方法写在接口中, 不让实现类看到, 有很好的安全性

类和接口之间的关系:
 ____________________________________

 |  名称  |    关键字  |  关系    |

 |------------------------------------|

 | 类和类的 |  extends    | 支持单继承 |

 | 类和接口 |  implements | 支持多实现 |

 |接口和接口|  extends    | 支持多继承 |

 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
抽象类和接口的主要区别:
  • 定义抽象类的关键字是 abstract class,而接口是 interface;

  • 继承抽象类的关键字是 extends,而实现接口的关键字是 implements;

  • 继承抽象类支持单继承,而实现接口支持多实现;

  • 抽象类中可以有构造方法,而接口不可以有构造方法;

  • 抽象类可以有成员变量, 而接口只有常量;

  • 抽象类可以有成员方法,接口只有抽象方法 (Java 7);
    新增支持非抽象方法和静态方法 (Java 8 新特性),但非抽象方法需要default关键字修饰
    新增支持私有方法 (Java 9 新特性)

  • 抽象类中增加方法时子类可以不用重写,接口增加方法时实现类需要重写 (Java 8 之前)
    接口使用默认方法让实现类选择是否重写 (Java 8)


特殊类

普通类的内容:

成员变量, 成员方法, 构造方法,
静态成员, 构造块, 静态代码块,
内部类

内部类 -- Inner Class

当一个类的定义出现在另外一个类的类体中时,那么这个类叫做内部类(Inner),而这个内部类所在的类叫做外部类(Outer)。

存在价值:仅仅为某个类单独服务时,可以将这个类定义为所服务的内部类。 隐藏该类的实现细节,并且可以方便的访问外部类的私有成员,而不再需要提供公有的 get 和 set 方法。

内部类的分类:

普通内部类 -- 直接将一个类的定义放在另外一个类的类体中;
静态内部类 -- 使用 static 关键字修饰的内部类, 隶属于类层级;
局部内部类 -- 直接将一个类的定义放在方法体的内部;
匿名内部类 -- 指没有名字的内部类

普通(成员)内部类

格式:

访问修饰符 class 外部类的类名 {

     访问修饰符 class 内部类的类名 {

          内部类的类体;
    }
}

使用方法:

Outer.Inner innerObj = new Outer().new Inner();

编译后: Outer$Inner.class
  • 和普通类一样可以定义成员变量, 成员方法以及构造方法等;
  • 和普通类一样可以使用 final 或 abstract;
  • 可以额外使用 private 或 protected 进行修饰;
  • 需要外部类对象来创建对象;
  • 访问外部类中与本类内部同名的成员变量或方法时,需要使用 this 关键字和"外部类名.this"的方式区分
静态内部类

格式:

访问修饰符 class 外部类的类名 {
  
      访问修饰符 static class 内部类的类名 {
 
             内部类的类体;
     }
 
}

使用方式:

StaticOuter.StaticInner staticInnerObj = new StaticOuter.StaticInner();
 
编译后: StaticOuter$StaticInner.class
  • 不能直接访问外部类的非静态成员,可以通过 new 外部类对象来访问非静态成员;
  • 可以直接创建对象;
  • 访问外部类中与本类内同名的成员变量或方法时,需要使用"类名."的方式区分。
局部(方法)内部类

格式:

访问修饰符 class 外部类的类名 {
 
    访问修饰符 返回值类型 成员方法名 (形参列表) {
 
        class 内部类的类名 {
 
            内部类的类体;
 
        }
 
    }
 
}

使用方式:

OuterClass outerObj = new OuterClass;

outerObj.outerMethod(args);

编译后: "OuterClass$1InnerClass.class"
  • 只能在该方法的内部使用;
  • 可以在方法体内部直接创建对象;
  • 不能使用访问控制符和 static 关键字修饰符;
  • 可以使用外部方法的局部变量, 但必须是 final 的;
  • 由局部内部类和局部变量的声明周期不同所致。
匿名内部类

格式:

接口/父类类型 引用变量名 = new 接口/父类类型() {
 
    方法的重写;
 
}

使用方式:

 
     MyInterface n = new MyInterface() {
 
         ... overridedMethod(...) {
 
             ...
 
         }}; n.overridedMethod(...);
 
     编译后: "MyInterface$1.class"
  • 可以实现接口或者继承父类;
  • 类本身没有名字, 其引用对象可以有名字;
  • 匿名对象加匿名内部类一起使用时,编译后不会出现对应的字节码文件;
  • 从 Java 8 开始提出新特性 Lamda 表达式可以简化。
回调模式:
  • 调用一个方法, 其参数是接口类型:需要创建一个实现此接口类型的对象,该方法在运行时会调用到参数对象所实现的方法。
  • 接口/继承类的引用作为方法形参时, 实参的传递方式:
    自定义类实现接口/继承类并重写方法,然后创建该对象作为实参传递;
    使用匿名内部类的语法格式得到接口/继承类的引用

枚举 -- Enum

-- 在日常生活中这些事物的取值只有明确的几个固定值,此时描述这些事物的所有值都可以一一列举出来,而这个列举出来的类型就叫做枚举类型。

  • 从 Java 5 开始增加的一种引用数据类型;

  • 使用 public static final 表示的常量描述较为繁琐,使用 enum 关键字来定义枚举类型取代常量;

  • 枚举值就是当前类的类型, 也就是指向本类的对象,
    默认使用 public static final 关键字共同修饰
    因此采用"枚举类型."的方式调用

  • 可以自定义构造方法,但构造方法修饰符必须是 private,默认也是 private

所有枚举类都自动继承 java.lang.Enum 类, 常用方法如下:

static T[] values() : 返回当前枚举类中的所有对象

String toString() : 返回当前枚举类对象的名称

int ordinal() : 获取枚举对象在枚举类的索引位置

static T : 将参数指定的字符串名转为当前

valueOf(String str) : 枚举类的对象

int compareTo(E o) :比较两个枚举对象在定义时的顺序

枚举类实现接口方式:
枚举类实现接口后需要重写抽象方法, 而重写方式有两种:

  1. 重写一个,跟普通类一样。
  2. 每个对象都重写,利用了匿名内部类功能。
     public enum DirectionEnum implements MyInterface {
 
         UP("上") {
 
             @Override

             ... overridedMethod(...) {
 
                 ...
 
             }
 
         },
         DOWN("下") {...},
 
         LEFT("左") {...},
 
         RIGHT("右"){...};
 
         private final String desc;
 
         private DirectionEnum(String desc) {
 
             this.desc = desc;
 
         }
 
        public String getDesc() {
 
             return desc;
 
         }
 
         //@Override
 
         //... overridedMethod(...) {
 
         //    ...
 
         //}

     }

注解 -- Annotation

从 Java 5 开始增加的一种引用数据类型,本质上就是代码的特殊标记,通过这些标记可以在编译, 类加载,以及运行时执行指定的处理

注解语法格式:

     访问修饰符 @interface 注解名称 {
 
         注解成员;
 
     }

自定义注解自动继承Java.lang.annotation.Annotation 接口
通过@注解名称的方式可以修饰:包, 类, 成员方法, 成员变量,构造方法, 参数, 局部变量的声明等。

注解使用方式:

  1. 注解体中只有成员变量, 没有成员方法:注解成员变量以"无形参的方法"形式来声明;
    其方法名定义了该成员变量的名字
    其返回值定义了该成员变量的类型

  2. 如果注解中没有任何成员,则该注解叫做标记注解/标识注解;

  3. 如果注解只有一个参数成员,建议使用参数名为 value
    而类型只能是:八种基本数据类型,String 类型,Class 类型(泛型, 如: Class<?> 或 Class<T>),enum 类型,Annotation 类型;

  4. 注解不支持继承

 public @interface MyAnnotation {
 
     public String value() default "123";
 
     public String value2();
 
 }
 @MyAnnotation(value = "hello", value2 = "456")
 
 public class Person {
 
     ...
 
 }
元注解 -- meta-annotation

-- 可以注解到注解上的注解
-- 元注解是一种基本注解, 但它能够应用到其它注解上

元注解主要有:
@Retention, @Documented, @Target,@Inherited,@Repeatable

元注解 @Retention

-- 用于说明该注解的生命周期

  • RententionPolicy.SOURCE 只在源码阶段保留
    在编译器进行编译时它将被丢弃忽视;

  • RententionPolicy.CLASS 保留到编译进行的时候
    不会被加载到 JVM, 默认方式;

  • RententionPolicy.RUNTIME 保留到程序运行的时候
    会被加载到 JVM 中, 程序运行时可以获取

元注解 @Documented

-- 注解将被 javadoc 工具提取进文档;
-- javadoc 工具从程序源代码中抽取类, 成员等注释,形成一个和源代码配套的 API 帮助文档,而该工具抽取时不包括注解本身;
-- 必须设置 Retention 值为 RUNTIME;

元注解 @Target

-- 指定能用于哪些元素的修饰

ElementType.ANNOTATION_TYPE:可以给一个注解进行注解

ElementType.CONSTRUCTOR : 可以给构造方法进行注解

ElementType.FIELD : 可以给属性进行注解

ElementType.LOCAL_VARIABLE :可以给局部变量进行注解

ElementType.METHOD : 可以给方法进行注解

ElementType.PACKAGE : 可以给包进行注解

ElementType.PARAMETER : 可以给方法内的参数进行注解

ElementType.TYPE : 可以给类型进行注解, 如类

从 Java 8 开始 @Target 的参数类型枚举值增加两个:

ElementType.TYPE_PARAMETER : 能写在类型变量的声明语句中, 如泛型

ElementType.TYPE_USE : 能标注任何类型名称 Use of a type

元注解 @Inherited

-- 子类继承超类的注解
注解本身不可以继承,如果一个超类被该注解标记过的注解进行注解时,如果子类没有任何注解应用时,则子类就继承超类的注解。

元注解 @Repeatable

-- 表示自然可重复的含义
从 Java 8 开始增加的新特性

常见的预制注解,是 Java 语言自身提供的注解, 具体如下:

| @author |表明类模块的作者, 多个作者用逗号隔开

| @version|表明该类模块的版本

| @see |参考转向, 也就是相关主题

| @since |从哪个版本开始增加的

| @param |对方法中某参数的说明, 如果没有参数就不能写

| @return |对方法返回值的说明, 类型为 void 就不能写

|----------------------------------------------------|

|@Override |限定重写父类方法, 该注解只能用于方法 |

|@exception |对方法可能抛出的异常进行说明 |

|@Deprecated|用于表示所修饰的元素(类, 方法)等已过时 |

|----------------------------------------------------|

| @SuppressWarnings | 抑制编译器警告 |

常见异常:
  • IllegalArugumentException :非法参数异常

  • ClassCastException: 类型转换异常

  • NullPointException : 空指针异常

  • ArithmeticException :算术异常

  • ArrayIndexOutOfBoundsException :数组下标越界异常

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 212,222评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,455评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,720评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,568评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,696评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,879评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,028评论 3 409
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,773评论 0 268
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,220评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,550评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,697评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,360评论 4 332
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,002评论 3 315
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,782评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,010评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,433评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,587评论 2 350

推荐阅读更多精彩内容