static

实例方法就是对象的一个行为。
静态方法就是类的一个行为。
 
 
 
 
当变量是静态变量的时候,内存是怎样的?
 
案例1:
/*
    static:
        1 static翻译为“静态的”
        2 所有static关键字修饰的都是类相关的,类级别的
        3 所有static修饰的,都是采用“类名.”的方式访问。
        4 static修饰的变量:静态变量
        5 static修饰的方法:静态方法
        
    变量的分类:
        变量根据声明的变量叫做:局部变量。
        在方法体外声明的变量叫做:成员变量。
        
    成员变量又可以分为:
        实例变量
        静态变量
*/

class VarTest{
    // 以下实例的,都是对象相关的,访问时采用“引用.”的方式访问。需要先new对象。
    // 不需要对象的参与即可访问。没有空指针异常的发生。
    // 成员变量中的实例变量
    int i;
    
    // 实例方法
    public void m2(){
        int x = 100; // 局部变量
    }
    
    // 以下静态的,都是类相关的,访问时采用“类名.”的方式访问。不需要new对象。
    // 实例相关的,必须先有对象,才能访问,可能会出现空指针异常。
    // 成员变量中的静态变量
    static int k;
    
    // 静态方法
    public static void m1(){
        int m = 200; // 局部变量
    }
}

 

案例2:

/*
    什么时候变量声明为实例的,什么时候声明为静态的?
        如果这个类型的所有对象的某个属性值都是一样的,不建议定义为实例变量,浪费空间。
        建议定义为类级别特征,定义为静态变量,在方法去中只保留一份,节省内存开销。
        
    一个对象一份的是实例变量。
    所有对象一分的是静态变量。
*/
/*public class StaticTest02{
    public static void main(String[] args){
        Chinese c1 = new Chinese("121231321312313","张三","中国");
        System.out.println(c1.idCard);
        System.out.println(c1.name);
        System.out.println(c1.countru);
        
        Chinese c2 = new Chinese("654654654646678","李四","中国");
        System.out.println(c2.idCard);
        System.out.println(c2.name);
        System.out.println(c2.countru);
        
    }
}

class Chinese{
    // 身份证号
    // 每一个人的身份证号不同,所以身份证号因该是实例变量,一个对象一份
    String idCard;// 一个对象一份
    // 姓名
    // 姓名也是一个人一个姓名,姓名也应该是实例变量。
    String name;
    // 国籍
    // 对于“中国人”这个类来说,国籍都是“中国”,不会随着对象的改变而改变。
    // 显然国籍并不是对象界别的特征。
    // 国籍属于整个类的特征,整个族的特征。
    // 假设声明为实例变量,内存图是怎样的?
    // 假设声明为静态变量,内存图又是怎样的?
    String countru;
    
    public Chinese(){
    
    }
    
    public Chinese(String s1,String s2,String s3){
            idCard = s1;
            name = s2;
            countru = s3;
    }
}*/

public class StaticTest02{
    public static void main(String[] args){
        
        Chinese c1 = new Chinese("121231321312313","张三");
        System.out.println(c1.idCard);
        System.out.println(c1.name);
        // 访问中国人的国籍
        // 静态变量应该使用类名.的方式访问。
        System.out.println(Chinese.countru);
        
        Chinese c2 = new Chinese("654654654646678","李四");
        System.out.println(c2.idCard);
        System.out.println(c2.name);
        
        // idCard是实例变量,必须先new对象,通过“引用.”访问
        // System.out.println(Chinese.idCard);//错误: 无法从静态上下文中引用非静态 变量 idCard
        
    }
}

class Chinese{
    // 身份证号
    // 每一个人的身份证号不同,所以身份证号因该是实例变量,一个对象一份
    String idCard;// 一个对象一份
    // 姓名
    // 姓名也是一个人一个姓名,姓名也应该是实例变量。
    String name;
    // 国籍
    // 重点重点五颗星:加static的变量叫做静态变量
    // 静态变量在类加载时初始化,不需要new对象,静态变量的空间就开出来了。
    // 静态变量存储在方法区。
    static String countru = "中国";
    
    public Chinese(){
    
    }
    
    public Chinese(String s1,String s2){
            idCard = s1;
            name = s2;
    }
}

 

案例3:

/*
    实例的:一定需要使用“引用.”来访问。
    静态的:
        建议使用“类名.”来访问,但使用“引用.”也行(但是不建议使用“引用.”)。
        静态的如果使用“引用.”来访问会让程序员产生疑惑:程序员会以为是实例的呢。
        
    结论:
        空指针异常只有在什么情况下才会发生呢?
            只有在“空引用”访问“实例”相关的,都会出现空指针异常。
*/
public class StaticTest03{
    public static void main(String[] args){
        System.out.println(Chinese.country);
        
        Chinese c1 = new Chinese("1111","张三");
        System.out.println(c1.idCard);
        System.out.println(c1.name);
        System.out.println(c1.country);
        
        // c1是空引用
        c1 = null;
        // 分析这里会不会出现空指针异常?
        // 不会出现空指针异常
        // 因为静态变量不需要对象的存在。
        // 实际上以下的代码在运行的时候,还是:ystem.out.println(Chinese.country);
        System.out.println(c1.country);
        
        // 这个会出现空指针异常,因为name是实例变量。
        // Exception in thread "main" java.lang.NullPointerException
        // System.out.println(c1.idCard);
    }
}

class Chinese{
    String idCard;
    String name;
    static String country = "中国";
    
    public Chinese(){
        
    }
    
    public Chinese(String a,String b){
        idCard = a;
        name = b;
    }
}

 

案例4:

public class StaticTest04{
    public static void main(String[] args){
        StaticTest04.doSome();
        StaticTest04 s = new StaticTest04();
        // 用“引用.”访问
        s.doSome();
        s.doOther();
        //空引用
        s= null;
        // 不会出现空指针异常
        StaticTest04.doSome();// 这个代码在最终执行的时候还是会转变为:StaticTest04.doSome();
        
        // 实例方法doOther()
        // 对象级别的方法(先new对象,通过“引用.”来访问)
        // 错误: 无法从静态上下文中引用非静态 方法 doOther()
        //StaticTest04.doOther();
        
        
    }
    
    // 静态方法(静态方法不需要new对象,直接使用“类名.”来访问)
    // 但是也可以使用“引用.”来访问,但是不建议用。(因为其他程序员你会感到困惑。)
    public static void doSome(){
    System.out.println("静态方法doSome()执行了!");    
        }
    
    // 实例方法(实例相关的都需要new对象,使用“引用.”来访问)
    public void doOther(){
        System.out.println("实例方法doOther()执行了!");    
    }
}

// 从第一天开始讲解HelloWorld到目前为止,一个类当中一共就写过这些东西。
/*
    类{
        // 实例线管的都是需要new对象的,通过“引用.”访问
        实例变量;
        实例方法;
        
        // 静态相关的都是采用“类名.”访问。也可以使用“引用.”,只不过不建议。
        静态变量;
        静态方法;
    }
*/

 

案例5:

/*
    关于方法来说,什么时候定义为实例方法?什么时候定义为静态方法?
        有没有参考标准
        
        此方法一般都是描述了一个行为,如果说该行为必须由对象去触发,那么该方法定义为实例方法。
        
        参考标准:
            当这个方法体当中,直接访问了实例变量,这个方法一定是实例方法。
            
            我们以后开发中,大部分情况下,如果是工具类的话,工具类当中的方法一般都是静态的。(静态方法有一个优点,是不需要new对象,直接采用类名调用
                及其方便。工具类就是为了方便,所以工具类中的方法一般都是static的。)
                
            什么是工具类???
                以后讲。(工具类就是为了方便变成而开发的一些类。)
    
    类 = 属性 + 方法
        属性描述的是:状态
        方法描述的是:行为动作
    
    一个方法代表了一个动作
    
    什么时候方法定义为实例方法?
        张三考试,得分90
        李四考试,得分100
        不同的对象参加考试的结果不同
        我们可以认定“考试”这个行为是与对象相关的行为。
        建议将“考试”这个方法定义为实例方法。
*/
public class StaticTest05{
    public static void main(String[] args){
        
            User x = new User();
            x.printName1();
    }
}

class User{
    //实例变量,需要对象
    private int i;
    
    private String name;// 首先分析的是,这个name方法是对象级别的,一个对象一份。
    
    // 分析这个方法应该定义为实例方法还是静态方法呢?
    // 打印用户的名字这样的一个方法
    public void printName1(){
        System.out.println(name);
    }
    
    public static void printName2(){
        // 输出的是一个对象的name
        //System.out.println(name);
    }
    
    public static void setId(int id){
        id = i;
    }
    
    public static int getId(){
        return id;
    }
}

 

 
案例6:
/*
    1 使用static关键字可以定义:静态代码块
    2 什么是静态代码块,语法是什么?
        static {
            java语句;
            java语句;
        }
    3 static静态代码块在什么时候执行呢?
        类加载时执行。并且只执行一次
        静态代码块有这样的特征/特点。
    
    4 注意:静态代码块在类加载时执行,并且在main方法执行之前执行。
    
    5 静态代码块一般是按照自上而下的顺序执行。
    
    6 静态代码块有啥作用,有什么用?
        第一:静态代码块不是那么常用。(不是每一个类当中都要写的东西。)
        第二:静态代码块这种语法机制实际上是SUN公司给我们java程序员的一个特殊的时刻/时机。
        这个时机叫做:类加载时机。
    
    具体的业务:
        项目经理说了:大家注意了,所有我们编写的程序中,只要是类加载了,请记录一下类加载的日志信息(在哪年哪月哪日几时几分几秒,哪个类加载到JVM当中了)
        思考:这些记录日志的代码写到哪里了呢?
            写到静态代码块当中。
*/
public class StaticTest06{
    public static void main(String[] args){
        
        System.out.println("Hello World");
    }
    // 静态代码块(特殊的时机:类加载时机。)
        static {
            System.out.println("A");
        }
        
        // 一个类当中可以编写多个静态代码块。
        static {
            System.out.println("B");
        }
        
        static {
            System.out.println("C");
        }
}

 

案例7:

/*
    
*/
public class StaticTest07{
    
    // 静态变量在什么时候初始化?类加载时初始化。
    // 静态变量存储在那里?方法区
    static int i = 100;
    
    // 静态代码块什么时候执行?类加载时执行。
    static {
        // 这里可以访问i吗?
        System.out.println("i= " + i);
    }
    
    int k = 111;// k变量是实例变量,在构造方法执行时内存空间才会开辟。
    
    static String name = "zhangsan";
    
    static {
        // k变量可以访问吗?
        // static静态代码块在类加载时执行,并且只执行一次。
        // 类加载时,k变量空间还没有开辟出来呢。
        //System.out.println("k+ " + k);
        
        // 这里可以访问这个namen吗?
        System.out.println("name= " + name);
    }
    
    // 静态变量在静态代码块下面。
    // 错误: 非法前向引用
    // 静态代码块和静态变量都在类加载的时候执行,时间相同,只能靠代码的顺序来决定谁先谁后。
    // static String name = "zhangsan";
    
    // 入口(main方法执行之前实际上执行了很多代码?)
    public static void main(String[] args){
        System.out.println("main Begin");
    }
}

/*
    总结:
        到目前为止,你遇到的所有java程序,有顺序要求的是哪些?
            第一:对于一个方法来说,方法体中的代码是有顺序的,遵循自上而下的顺序执行。
            第二:静态代码块1和静态代码块2是有先后顺序的。
            第三:静态代码块和静态变量是有先后顺序的。
*/

 

案例8:

/*
    1 除了静态代码块之外,还有一种语句块叫做:实例语句块。
    2 实例语句在类加载时并没有执行。
    3 实例语法语句:
        {
        
        }
    4 实例语句块在什么时候执行?
        只要是构造方法执行,必然在构造方法执行之前,自动执行“实例语句快”中的代码。
        实际上这也是SUN公司为java程序员准备的一个特殊的时机,叫做对象构建时机。
*/
public class InstanceCode{
    public static void main(String[] args){
        System.out.println("main begin");
        new InstanceCode();
        new InstanceCode();
    }
    
    // 实例语句块
    {
        System.out.println("实例语句块执行。");
    }
    
    public InstanceCode(){
        System.out.println("无参数的构造方法");
    }
    
    public InstanceCode(String name){
        System.out.println("有参数的构造方法");
    }    
}

 

案例9:

// 判断一下程序的执行顺序
public class CodeOrder{
    
    //静态代码块
    static{
        System.out.println("A");
    }
    
    // 入口
    public static void main(String[] args){ // A X main Begin C B main Over
            System.out.println("main Begin");
            new CodeOrder();
            System.out.println("main Over");
    }
    
    // 构造方法
    public CodeOrder(){
        System.out.println("B");
    }
    
    // 构造代码块
    {
        System.out.println("C");
    }
    
    //静态代码块
    static {
        System.out.println("X");
    }
}
posted @ 2020-06-06 00:05  xlwu丶lz  阅读(203)  评论(0编辑  收藏  举报