Java修饰符

访问修饰符

非访问修饰符

访问控制四个修饰符

访问控制修饰符定义类、变量、方法的访问权限。Java支持4种访问控制修饰符:public, protected, default, private.

  • public:修饰类、接口、方法、变量,所修饰的对象对所有类可见。
  • protected:修饰变量和方法,所修饰的对象对同一包内的类可见,若子类不在同一个包内,则该子类只能访问其继承的成员。(详情见Java protected 关键字详解)
  • default:修饰类、接口、方法、变量,当缺省访问控制修饰符时默认为default,所修饰的对象在同一包内可见。
  • private:修饰变量和方法,所修饰的对象只在同一类内可见。用private修饰的变量不能被外部直接访问,通常需要通过getter和setter方法间接访问,实现对对象成员变量的保护。
  • Demo1.java
/**
 * @author: 毛利
 */
public class Demo1 {
    // static ,非访问修饰符,静态变量;final,非访问修饰符,使变量不可变,结合static就成了常量
    private static final int NUM1 = 1;
    public static final int NUM2 = 2;
    protected static final int NUM3 = 3;
    static final int NUM4 = 4;

    public static void main(String[] args) {
        System.out.println(NUM1);
        System.out.println(NUM2);
        System.out.println(NUM3);
        System.out.println(NUM4);
    }
}
  • 在同级新建Demo2 .java
/**
 * @author: 毛利
 */
public class Demo2 extends Demo1 {
    public static void main(String[] args) {
//        System.out.println(NUM1); 报错 无法访问
        System.out.println(NUM2);
        System.out.println(NUM3);
        System.out.println(NUM4);
    }
}
  • 在上级新建Demo3.java
/**
 * @author: 毛利
 */
public class Demo3 extends Demo1 {
    public static void main(String[] args) {
//        System.out.println(NUM1); 
        System.out.println(NUM2);
        System.out.println(NUM3);
//        System.out.println(NUM4); //报错
    }
}

重点: 父类中声明为 public 的方法在子类中也必须为 public。 父类中声明为 protected 的方法在子类中要么声明为 protected,要么声明为 public,不能声明为 private。 父类中声明为 private 的方法,不能够被继承

  • 在另一个包新建Demo4,不采用继承的方法
/**
 * @author: 毛利
 */
public class Demo4 {
    public static void main(String[] args) {
        Demo1 demo1 = new Demo1();
        System.out.println(demo1.NUM2);

//        System.out.println(demo1.NUM3); 报错
//        System.out.println(demo1.NUM4); 报错

    }
}

非访问修饰符

  • static 修饰符

首先,了解下成员变量

成员变量

成员变量可以分为:

  • 实例属性 (不用static修饰) 随着实例属性的存在而存在
  • 类属性 (static修饰) 随着类的存在而存在

一种是被static关键字修饰的变量,叫类变量或者静态变量, 另一种没有static修饰,为成员变量,是通过创建对象来访问

Demo5.java

/**
 * @author: 毛利
 */
public class Demo5 {
    static final int num1 = 1;
    int num2;

    Demo5(){
        this.num2 = 2;
    }
    public static void main(String[] args) {
        System.out.println(" 静态变量 num1=" + Demo5.num1);
        Demo5 demo5 = new Demo5();
        System.out.println("实例变量 num2=" + demo5.num2);
    }
}

补充局部变量

局部变量:形参、方法内定义的变量、代码块中定义的变量,都属于局部变量。

静态变量属于整个类所有,而不是某个对象所有,即被类的所有对象共享。

补充:JAVA中初始化的顺序:

  • 加载类;
  • 静态变量初始化;
  • 静态块;【其只能调度静态的】
  • 成员变量;
  • 构造方法;
Demo6.java
/**
 * @author: 毛利
 */
public class Demo6 {
    // 静态变量
    // 2.第二步,静态变量和静态代码块的加载顺序由编写先后决定
    static int num = 4;
    // 静态块
    static {
        System.out.println("开始执行静态代码块");
        // 3.第三步,静态块,然后执行静态代码块,因为有输出,故打印a
        System.out.println("a");
        System.out.println(num);
    }

    public static void main(String[] args) {
        System.out.println("开始创建类");
        //4.第四步,new一个类,但在new之前要处理匿名代码块
        new Demo6();
    }


    // 匿名代码块
    {
        System.out.println("开始加载匿名代码块");
        num += 3;
        //5.第五步,按照顺序加载匿名代码块,代码块中有打印
        System.out.println("b");
        System.out.println(num);
    }

    //6.第六步,按照顺序加载变量
    int a = 5;

    // 按照顺序加载匿名代码块 匿名代码块本身就是成员变量
    {
        //7.第七步,按照顺序打印c
        System.out.println("c");
    }

    // 类的构造函数,第四个加载
    Demo6() {
        //8.第八步,最后加载构造函数,完成对象的建立
        System.out.println("d");
        System.out.println(a);
    }
    // 静态方法,调用的时候才加载
    static void run()                    
    {
        // 静态方法没有执行
        System.out.println("e");
    }
}

Staic

static是静态修饰符,什么叫静态修饰符呢?在程序中任何变量或者代码都是在编译时由系统自动分配内存来存储的,而所谓静态就是指在编译后所分配的内存会一直存在,直到程序退出内存才会释放这个空间,也就是只要程序在运行,那么这块内存就会一直存在。

在Java程序里面,所有的东西都是对象,而对象的抽象就是类,对于一个类而言,如果要使用他的成员,那么普通情况下必须先实例化对象后,通过对象的引用才能够访问这些成员,但是有种情况例外,就是该成员是用static声明

Demo7.java
/**
 * @author: 毛利
 */
public class Demo7 {
     /*
    总结如下

    static修饰静态方法:
    会使得这个方法成为整个类所共有的方法,可以用“类名.方法名”访问。
    static修饰的方法,不能直接访问本类中非静态成员,但是本类中的非静态方法可以访问静态成员。
    在静态方法中不能出现this关键字。
    Java中的main方法必须写成static的原因:在类加载时无法创建对象,而静态方法可以不通过对象调用,所以在类加载时就可以通过main方法入口来运行程序。
     */

     int num1 = 1;
     static int num2 = 2;

    // 静态demo方法
    static void demo(){

        // System.out.println("num1="+num1); 报错
        // 因为静态demo方法不能使用非静态成员num1

        System.out.println("num2"+num2);
    }

    public void demo1(){

        //但是本类中的非静态方法可以访问静态成员

        System.out.println(num1);
        System.out.println(num2);


    }

    public static void main(String args[]){
        // 执行静态demo方法
        demo();


        // demo1() 报错

        /*
        因为对于一个类而言,如果要使用他的成员,那么普通情况下必须先实例化对象后,通过对象的引用才能够访问这些成员
         */

        Demo7 demo7 = new Demo7();
        System.out.println("执行demo1方法 ");
        demo7.demo1();

    }

    // 一旦类被加载,所有的static语句被运行。
    static{
        System.out.println("demo7类被加载");
        num2 = num2 + 1 ;
        // num2 = 3 
    }
}

final 修饰符

final修饰类即表示此类已经是“最后的、最终的”含义。

因此,用final修饰的类不能被继承,即不能拥有自己的子类。

public final  class Demo8 {}
public class  Demo9 extends Demo8{} // 报错

final修饰的变量值也不可被改变。

final 方法可以被子类继承,但是不能被子类重写。

final 修饰符通常和 static 修饰符一起使用来创建类常量。

/**
 * @author: 毛利
 */
public class Demo8 {

    final int num1 = 1;

    {
        // num1 +=1 ; // 报错
        //System.out.println(num1);
    }

    // public static final 通常创建静态变量 一般要大写
    public static final int NUM2  = 2;


    public static void main(String[] args)  {
        String a = "Maoli";
        final String b = "Mao";
        String d = "Mao";
        String c = b + "li";
        String e = d + "li";


        System.out.println((a == c)); // true

        // 在编译期间能知道b的确切值,则编译器会把它当做编译期常量使用
        // 直接访问的这个常量,不需要在运行时确定 编译器进行了优化

        System.out.println((a == e)); // false


        //基本数据类型
        final int i = 1;



        //引用类型,引用test类
        final Test t = new Test("Maoli今年20年,专业化工");
        System.out.println(t.getStr());

        // 重新setStr的值,没问题,说明变量本身指向的对象的值可以改变
        t.setStr("谁说不是计算机的不会Java?");//
        System.out.println(t.getStr());

        //试着重新new一个test给t对象,
        t = new Test("重新new一个test给t对象,竟然报错了");
        //变量的引用不可以改变
    }

}

class Test{
    private String str;

    public Test(String str) {
        this.str = str;
    }

    public String getStr() {
        return str;
    }


    public void setStr(String a) {
        this.str = a;
    }
}

abstract 修饰符

abstract 抽象

这个类成为一个抽象类,这个类将不能生成对象实例

一个类不能同时被 abstract 和 final 修饰。子类继承并覆盖其中的抽象方法。

  • Dome9.java
/**
 * @author: 毛利
 */

public abstract class Demo9{

    String name = "maoli";
    String year = "199910";

    public abstract void getname(); //抽象方法
    public abstract void getyear();

    private void print111(){
        System.out.println(111);
    }
    public void print222(){
        System.out.println(222);
    }
}


class Maoli extends Demo9{

    // 需要子类继承并覆盖其中的抽象方法。
    @Override
    public void getname() {
        System.out.println("我的网名: "+ name);
    }

    @Override
    public void getyear() {
        System.out.println("我的出生年月" + year);
    }

    public static void main(String[] args) {
        Maoli maoli = new Maoli();
        maoli.getname();
        maoli.getyear();
    }
}

synchronized 和 volatile 修饰符

  • synchronized:同步的;同步化的
  • volatile:不稳定的;爆炸性的;反复无常的

synchronized 和 volatile 修饰符主要用于线程的编程。

volatile是轻量级的synchronized,在多处理器(多线程)开发中保证了共享变量的“可见性”。

可见性表示当一个线程修改了一个共享变量时,另外一个线程能读到这个修改的值。

由于涉及Java多线程,篇幅难度更大,本文先断

本文分享自微信公众号 - Python之王(gh_70a22bfa8e3a),作者:小sen

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2019-10-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Java编程题目(一)

    闰年的判断规则如下: (1)若某个年份能被 4 整除但不能被 100 整除,则是闰年。

    润森
  • 八十二、Python | Leetcode贪心算法系列

    作者介绍:Runsen目前大三下学期,专业化学工程与工艺,大学沉迷日语,Python, Java和一系列数据分析软件。导致翘课严重,专业排名中下。.在大学60%...

    润森
  • Java编程题目(三)

    分别赋一些随机整数,然后求出所有元素 的最大值, 最小值,平均值,和值,并输出出来。

    润森
  • 一份Java基础知识笔试题附答案

    框架师
  • 第二节:Java入门第一行代码

    学习Java基础课程,学会使用eclipse,eclipse为Java集成开发坏境IDE,创建第一个Java源文件代码:

    达达前端
  • Java中的数字类解析(包括格式化数字、大数运算等等)

    Java中如果数据绝对值大于0.001而小于10000000用常规小数表示,否则采用科学计数法表示

    glm233
  • 字符串基础类型拓宽的操作,转换成整数值

    Jerry Wang
  • JavaSE(三)之static、final、abstract修饰符

    一、static修饰符 1.1、static变量         在类中,使用static修饰的成员变量,就是静态变量,反之为非静态变量。         ...

    用户1195962
  • 深入理解Java8 Lambda表达式

    匿名函数的应用场景是: 通常是在需要一个函数,但是又不想费神去命名一个函数的场合下使用Lambda表达式。lambda表达式所表示的匿名函数的内容应该是很简单...

    ZhangXianSheng
  • Java 反射

    JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对...

    赵哥窟

扫码关注云+社区

领取腾讯云代金券