美文网首页
java修饰符

java修饰符

作者: 幻想的绝望 | 来源:发表于2019-11-04 20:14 被阅读0次

概述

java修饰符有以下两种

  • 访问修饰符
    private:私有访问修饰符,仅类内可见
    protected:受保护,仅同包内可见
    defult:默认,仅同包内可见
    public:公有,所有包可见,只需导入包
  • 非访问修饰符
    static:用于声明静态方法,变量
    final:用于声明不可修改的类,方法,常量
    abstract:创建抽象类和抽象方法
    synchronized:声明的方法同一时间只能被一个线程访问
    transient:修饰的实例变量不会被序列化
    volatile:修饰的成员变量强制从共享内存中读取

static要点分析

static修饰的变量为类变量,修饰的方法为类方法,可通过类名直接调用。(修饰类,这个类就是静态内部类)
从jvm虚机机类加载角度看,静态资源是类初始化的时候加载的,而非静态资源是类new的创建对象的时候加载的。静态资源的加载早于非静态资源。所以静态方法不可以引用非静态资源,非静态方法可以引用静态资源。

public class A {
    private static int a = s2();

    static {
        System.out.println("this is s1");
    }

    static int s2() {
        System.out.println("this is s2");
        return 1;
    }

    public A() {
        System.out.println("this is A()");
    }

    public static void main(String[] args) {
        new A();
    }
}
输出结果
this is s2
this is s1
this is A()

说明静态资源的加载顺序是按照资源定义的顺序加载的,且先于非静态资源

public class B {
    static {
        i = 3;
        System.out.println(i);
    }
    private static int i;
}

第四行输出i编译器直接提示报错,说明静态代码块对于定义在它之后的静态变量,可以赋值,但是不能访问

public class C {
    static {
        System.out.println("c.static");
    }

    public C(){
        System.out.println("c.public");
    }
}

public class D extends C {
    static {
        System.out.println("d.static");
    }

    public D(){
        System.out.println("d.public");
    }

    public static void main(String[] args) {
        new D();
        new D();
    }
}

输出结果
c.static
d.static
c.public
d.public
c.public
d.public

说明静态代码先执行父类,再执行之类,且只执行一遍

public class Hello {

    public static void main(String[] args) {
        ClassLoader loader = Thread.currentThread().getContextClassLoader();
        printClassesOfClassLoader(loader);
        System.out.println("hello  " + A.class);
        printClassesOfClassLoader(loader);
    }

    public static void printClassesOfClassLoader(ClassLoader loader){
        try {
            Field classesF = ClassLoader.class.getDeclaredField("classes");
            classesF.setAccessible(true);
            Vector<Class<?>> classes = (Vector<Class<?>>) classesF.get(loader);
            for(Class c : classes) {
                System.out.println(c);
            }
        } catch (NoSuchFieldException e) {
            e.printStackTrace();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        }
    }
}

程序输出
class com.intellij.rt.execution.application.AppMainV2$Agent
class com.intellij.rt.execution.application.AppMainV2
class com.intellij.rt.execution.application.AppMainV2$1
class statics.Hello
hello  class statics.A
class com.intellij.rt.execution.application.AppMainV2$Agent
class com.intellij.rt.execution.application.AppMainV2
class com.intellij.rt.execution.application.AppMainV2$1
class statics.Hello
class statics.A

接着上面的A类,以上代码运行后,程序输出中并没有出现A中的静态代码块输出的内容,但是类加载器里面的确有了A类。为什么A.class这种方式不会触发A内的静态代码块的执行呢?
这就要提到java类加载的五个过程加载,验证,准备,解析,初始化。在Java方法区中创建A.Class的类信息发生在加载阶段,运行静态块内容则发生在初始化阶段

final要点分析

final修饰类,类不可被继承
final修饰方法,方法不可被重写
final修饰变量,变量不可改变

    public static void main(String[] args) {
        final String[] s = {"aaa", "bbb"};
        s[1] = "ccc";
        //s = new String[2];//无法使用,程序报错
    }

第三行没问题,第四行程序提示bug,说明变量的不可改变,指的是引用不可改变,但是引用指向的内容可以改变

final String s = "a"

重点说说这个,这个a存在于常量池中,s存储的是指向a的地址,如果把s赋值为"b",本质上是把s存储的地址改成b的,当然修改时不会成功的。所以本质上来说final修饰变量的时候确实是,不可变的是变量的引用而非引用指向对象的内容

其他要点分析

  1. 类默认和接口默认并不相同,接口变量默认为public static final,接口方法默认为public
  2. protected修饰符,经测试,子类父类在不同包,子类不可见父类的protected方法
public class Student extends People {

    protected void say4() {
        System.out.println("2");
    }

    public static void main(String[] args) {
        People p = new Student();
        //p.say4();//无法使用,会报错

        Student s = new Student();
        s.say4();
    }
}
想我所见,思我说闻
写我所想,写我所思
不求处处皆对 
只求问心无愧

相关文章

  • java学习笔记第二天

    java修饰符 java修饰符 java语言提供了很多修饰符,主要分为下面两类: 1.访问修饰符 2.非访问修饰符...

  • Java 修饰符

    Java 修饰符 Java语言提供了很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符 修饰符用来定义类、方...

  • 日常记忆Java修饰符

    Java修饰符 Java语言提供的很多修饰符,主要分为以下两类: 访问修饰符 非访问修饰符修饰符用来定义类、方法或...

  • Java知识之修饰符

    Java中的修饰符 Java中的修饰符主要分为两类: 访问控制修饰符 非访问控制修饰符 访问控制修饰符分: pub...

  • java修饰符有哪些?

    java修饰符有哪些? Java语言提供了很多修饰符,主要分为以下两类: 1、访问修饰符; 2、非访问修饰符。 (...

  • Java中访问修饰符和构造函数的一点总结

    Java访问修饰符 Java用于类的修饰符(2个)和限定符(2个) 注意:内部类可以拥有更多的访问修饰符 Java...

  • java基础-static

    概述 static 在java体系里的地位:java语言的一个修饰符,属于非访问修饰符,所谓访问修饰符就是控制访问...

  • 关于Java语言中那些修饰符

    一.在java中提供的一些修饰符,这些修饰符可以修饰类、变量和方法,在java中常见的修饰符有:abstract(...

  • java的访问修饰符

    一. Java中的访问修饰符 Java面向对象的基本思想之一是封装细节并且公开接口。Java语言采用访问控制修饰符...

  • Java修饰符

    引言:Java的修饰符根据修饰的对象不同,分为类修饰符、方法修饰符、变量修饰符;根据功能又分为访问控制修饰符和非访...

网友评论

      本文标题:java修饰符

      本文链接:https://www.haomeiwen.com/subject/qaecbctx.html