Java基础篇——特殊关键字

目录

1、this关键字

2、supper关键字

3、static关键字

3.1、static修饰方法

3.2 、static修饰变量

3.3、static修饰代码块

3.3、static修饰内部类

4、final关键字

4.1、final修饰类

4.2、final修饰方法

5、访问控制修饰符


Java语言中定义了很多关键字,比如this、supper、static、final、public、private等等。不同的关键字的用途不同,相同关键字用在不同的地方,作用也不同。本章挑选一些特殊关键字,分析它们的用法和用途。

1、this关键字

this表示对当前对象的引用,指向的是当前对象。当前对象指的是当前正在调用实例的成员对象,换言之:谁调用了方法,谁就是当前对象。

用法:

  • 调用类中的属性:this.属性名称,指的是访问类中的成员变量,用来区分成员变量和局部变量(重名问题)。可以在构造方法和成员方法中使用,不可以在静态方法中使用,因为构造方法和成员方法的局部变量表中包含 this 变量,而静态方法中不包含。
  • 调用类中的方法:this.方法名称,用来访问本类的成员方法或类方法(可以访问类方法,但是不建议使用this访问类方法,即使这样写了,编译器也会优化)。可以在构造方法和成员方法中使用(一般都是在成员方法中使用),不可以在静态方法中使用。
  • 调用类构造方法:this(),访问本类的构造方法,()中可以有参数的,如果有参数就是调用指定的有参构造。只能在构造方法中使用,并且只能作为构造方法的第一条语句。

 示例:

public class Person  {

    private String name;
    private String id;
    private static int age;

    public Person() {
        this.name = ""; // 调用实例变量
        this.id = ""; // 调用实例变量
        this.age = 0; // 调用类变量,相当于 age = 0 或 Person.ege = 0
    }

    public Person(String name, int age) {
        this();   // 调用无参构造,也可以调用有参构造
        this.name = name; // 调用实例变量
        //this();   // 不合法,只能放在构造方法第一行
        this.age = age; // 调用类变量,相当于 Person.ege = age
        this.eat();  // 合法,但一般不这样用
    }

    public void eat() {
        System.out.println("I am eating");
        this.name = "123"; // 成员方法中调用实例变量
        this.age = 15; // 调用类变量,相当于 age = 15 或 Person.ege = 15
        this.sleep(); // 调用成员方法
        this.walk(); // 调用静态方法,相当于 Person.walk()
    }

    public void sleep(){
        System.out.println("I am sleeping");
    }

    public static void walk() {
        //this();  //不合法,只能用在构造方法第一行
        System.out.println("I am walking");
        //this.name = "abc"; // 不合法
        //this.sleep(); //不合法
    }
}

2、supper关键字

super表示对当前对象的父类的引用,使用super来调用父类的构造方法和非私有的成员变量、方法。

用法:

  • 使用super调用父类中的非私有成员变量,可以从父类实例处获得信息。可以在构造方法和成员方法中使用,不可以在静态方法中使用。
  • 使用super调用父类中的方法,可以委托父类对象帮助完成某件事情。可以在构造方法和成员方法中使用(一般都是在成员方法中使用),不可以在静态方法中使用。
  • 使用super调用父类中的构造方法(super(实参)形式),必须在子类构造方法的第一条语句,调用父类中相应的构造方法,若不显示的写出来,默认调用父类的无参构造方法,比如:super();

示例:

public class Chinese extends Person {
    
    public Chinese() {
        super();
        super.addr = "";
        //super();  // 不合法
        super.addr = "super";
        super.eat();  //一般不这样用
        super.walk(); //一般不这样用
    }

    public void play() {
        //super();    // 不合法
        super.addr = "play";
        super.eat();
        super.walk(); // 一般写出Person.walk();
    }

    public static void cook() {
        //super();   // 不合法
        //super.addr = "play";   // 不合法
        //super.eat();   // 不合法
        //super.walk();   // 不合法
    }
}

3、static关键字

static是一个修饰符,用于修饰类的方法、变量,还可以在类中任意地方编写static代码块来优化程序性能,也可以修饰内部类。static关键字修饰的方法叫做静态方法,static关键字修饰的变量叫做类变量,类加载后,可以通过类名直接访问,不需要依赖于对象来进行访问(不需要不代表不可以,意思是也可以通过对象访问)。

3.1、static修饰方法

static修饰的方法一般称作静态方法,由于静态方法不依赖于任何对象就可以进行访问,因此对于静态方法来说,是没有this的,因为它不依附于任何对象,既然都没有对象,就谈不上this了。并且由于这个特性,在静态方法中不能访问类的非静态成员变量和非静态成员方法,因为非静态成员方法/变量都必须依赖具体的对象才能够被调用。

说明:

虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法和静态变量(又叫类变量)的。

3.2 、static修饰变量

static修饰的变量也称为静态变量,静态变量和非静态变量的区别是:静态变量被所有对象共享,在内存中只有一个副本,它当且仅当在类初次加载时会被初始化。而非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响。

static成员变量的初始化顺序按照定义的顺序进行初始化。

3.3、static修饰代码块

static关键字可以用来形成静态代码块以优化程序性能。static块可以置于类中的任何地方,类中可以有多个static块。在类初次被加载的时候,会按照static块的顺序来依次执行每个static块,并且只会执行一次。

static块可以优化程序性能,是因为它的特性:只会在类被初次加载的时候执行一次。如下:

public class Person{
    private Date birthDate;

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    boolean isBornBoomer() {
        Date startDate = Date.valueOf("1946");
        Date endDate = Date.valueOf("1964");
        return birthDate.compareTo(startDate)>=0 && birthDate.compareTo(endDate) < 0;
    }
}

isBornBoomer是用来判断一个人是否是1946-1964年出生的,而每次isBornBoomer被调用的时候,都会生成startDate和birthDate两个对象,造成了空间浪费,如果改成下面这样效率会更高:

public class Person {
    private Date birthDate;
    private static Date startDate, endDate;

    static {
        startDate = Date.valueOf("1946");
        endDate = Date.valueOf("1964");
    }

    public Person(Date birthDate) {
        this.birthDate = birthDate;
    }

    boolean isBornBoomer() {
        return birthDate.compareTo(startDate) >= 0 && birthDate.compareTo(endDate) < 0;
    }
}

3.3、static修饰内部类

定义的内部类前加static修饰符,此时的内部类就是静态内部类。通过一个例子来了解静态内部类都有哪些特点。

public class Outer {
    //定义一个实例变量和一个静态变量
    private int a;
    private static int b;
    //定义一个静态方法和一个非静态方法
    public static void say(){}
    public void test(){
        //在外部类中调用内部类的属性和方法
        Outer.Inner.c = 1;            //可以通过静态内部类的全类名来调用静态内部类的静态属性(外部类名.静态内部类名.属性)
        Outer.Inner.go();            //可以通过静态内部类的全类名来调用静态内部类的静态方法(外部类名.静态内部类名.方法)
        //Outer.Inner.walk();        //不能通过类静态内部类的全类名来调用内部类的非静态属性和方法
        Inner inner = new Inner();
        inner.d = 1;
        inner.walk();                    //可以通过创建内部类实例来调用静态内部类的非静态属性和方法
    }
    //静态内部类
    public static class Inner{
        //在静态内部类中定义一个静态变量和一个实例变量
        static int c;
        int d;
        //定义一个匿名代码块和一个静态代码块
        {}
        static{}
        //定义一个静态方法和一个普通方法
        public static void go(){}
        public void walk(){
            //在静态内部类中调用外部类的属性和方法
            int f = b;                     //可以直接调用外部类的静态属性
            say();                        //可以直接调用外部类的静态方法
            //int e = a;                 直接调用外部类的非静态属性出错编译出错
            //test();                    直接调用外部类的非静态方法时编译出错
            Outer outer = new Outer();
            int e = outer.a;            //可以通过创建外部类实例来调用外部类的非静态属性
            outer.test();                //可以通过创建外部类实例来调用外部类的非静态方法
        }
    }
}

总结:

1、静态内部类中可以写哪些内容

  • 匿名代码块
  • 静态代码块
  • 静态变量和非静态变量
  • 静态方法和非静态方法

注意:不能在静态内部类中写抽象方法

2、外部类如何调用静态内部类中的属性和方法

  • 外部类可以通过创建静态内部类实例的方法来调用静态内部类的非静态属性和方法
  • 外部类可以直接通过“ 外部类.内部类.属性(方法)” 的方式直接调用静态内部类中的静态属性和方法

3、静态内部类如何调用外部类的属性和方法 

  • 静态内部类可以直接调用外部类的静态属性和方法
  • 静态内部类可以通过创建外部类实例的方法调用外部类的非静态属性和方法

4、如何创建静态内部类实例

  • 在非外部类中:外部类名.内部类名 name = new 外部类名.内部类名();
  • 在外部类中:内部类名 name = new 内部类名();

4、final关键字

final是一个修饰符,意思是最终的、不可变的,由此可见被final修饰的内容都是不可变的。final可以修饰类、属性、方法。

4.1、final修饰类

当用final修改类时,该类成为最终类,无法被继承。比如java.lang包下的String类就是被final修饰的,任何类都不可以继承它。

4.2、final修饰方法

当使用final修饰方法时,这个方法将成为最终方法,无法被子类重写。但是,该方法仍然可以被继承。

4.2、final修饰属性

final修饰属性叫做常量,意思是属性一旦被赋值,内容不可以改变。如果修饰的是基本数据类型的属性,值本身不可以改变;如果修饰的是引用数据类型的属性,值本身不可变,但是引用的对象的内容是可变的

比如:

private final int i = 1; i 的值永远都是1,不可以修改。

private final List list = new ArrayList(); list 保存的永远是 new ArrayList() 对象的引用,但是 new ArrayList() 对象的值是可以改变的。

public class TestMain {

    public static void main(String[] args) {
        Animal ani = new Animal();
        ani.print();
    }
}

class Animal {

    private final int i = 1;
    private final List list = new ArrayList();

    public void print() {
//        this.i = 10;
//        this.list = new ArrayList();

        int j = i;
        j++;
        System.out.println("i = " + i);
        System.out.println("j = " + j);

        list.add("张三");
        for (Object obj:list) {
            System.out.println(obj);
        }
        System.out.println("---------------分割线------------");
        List newList = list;
        newList.add("李四");
        for (Object obj:list) {
            System.out.println(obj);
        }

    }

}

输出结果:

从上面示例代码中可以看出,常量只能进行一次赋值操作。int 类型(基本数据类型)的常量 i 的值没有改变, List 类型(引用数据类型)的常量 list 引用的对象的值发生了变化。

5、访问控制修饰符

Java中,可以使用访问控制符来保护对类、接口、变量、方法和构造方法的访问。Java 支持 4 种不同的访问权限。

  • default (即默认,什么也不写): 在同一包内可见,不使用任何修饰符。使用对象:类、接口、变量、方法。

  • private : 在同一类内可见。使用对象:变量、方法、内部类。 注意:不能修饰类(外部类)、接口

  • public : 对所有类可见。使用对象:类、接口、变量、方法

  • protected : 对同一包内的类和所有子类可见。使用对象:变量、方法、内部类。 注意:不能修饰类(外部类)、接口

 访问控制修饰符的方法、属性的访问权限一览表:

修饰符当前类同一包内子孙类(同一包)子孙类(不同包)其他包
publicYYYYY
protectedYYYYN
defaultYYYNN
privateYNNNN

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值