zoukankan      html  css  js  c++  java
  • 关键字this---static---final

      this和static都是java的关键字,它们用来表示一种数据类型,不能用做变量名,方法名,包名,参数。

    1.this关键字

    (1)this是一个引用,总是指向当前对象 

    class Student {
    	String name;
    	int age;
    	
    	Student(){}
    	Student(String name1,int age1){
    		name = name1;
    		age = age1;	
    	}
    	public void show(){
    		System.out.print("name="+name+"----"+"age="+age);
    	}
    
    }
    
    public class Person {
    	public static void main(String[] args) {
    		// TODO Auto-generated method stub
    		Student student = new Student("许巍",21);
    		student.show();	
    	}
    
    }
    

      运行结果:

      name=许巍----age=21

    下面我用内存图来讲解一下这个过程

    以上边的代码为例子,讲解一下内存的加载:图中主要分为三块,左边的是栈,右边的是堆,下边的一大块是内存方法区

    A.启动程序,Person.class的字节码文件(Person类编译后的文件)放到内存方法区中,执行main函数,main()进栈

    B.创建student对象,会调用Stundent.class,Stundent.class放到内存方法区中.

    C.在堆中创建对象会有默认值,age=0,name=null.因为创建对象时,传入了(“许巍”,21)---->age=21,name="许巍"

    D.堆中的对象有内容首地址,Student的内存首地址为0x456,将此地址给student,student指向堆中的new Student(“许巍”,21)

    E.调用show(),show函数有默认this,被省略了。

    System.out.print("name="+this.name+"----"+"age="+this.age);

    (2)局部变量和成员变量同名


     运行结果:

        前者name=null----age=0

        后者name=许巍----age=21

    来分析以下原因:

    局部变量和成员变量同名时,成员变量无效

    Student类的成员变量与有参构造函数Student(String name,int age)的局部变量同名,成员变量无效。

    (3)构造函数相互调用

     运行结果:

        前者:

          name=null----age=0
          name=许巍----age=21

        后者:name=许巍----age=21

    来分析以下原因:

    前者有参构造函数Student(String name,int age)调用this()<相当于调用Student()>,main()创建student对象,此时会在堆里创建对象,age=0,name=null(默认值),System.out.print()输出的值是:age=0,name=null

        参数传进后,age=21,name="许巍",调用show(),输出age,name变为传进的值。但是this()必须在构造函数的第一行,在其它位置会报错!

    后者无参构造函数Student()调用this(String name,int age)<相当于调用Student(String name,int age)>,main()创建student对象,此时会在堆里创建对象,age=0,name=null(默认值),参数传进后,age=21,name="许巍",调用show(),输出age,name变为传进的值。但是this()必须在构造函数的第一行,在其它位置会报错!

    2.static(静态的),修饰成员变量,成员函数

    (1)static修饰的成员变量的特点:

      A.static修饰的成员变量是该类的所有对象共享 

      B.static修饰的成员变量是随着类的加载就在静态区中开辟了内存,所以优于非静态成员变量开辟内存

      C.static修饰的成员变量可以通过类名直接访问,也可以通过对象访问。

    (2)静态成员与非静态成员变量的对比

      A.存储的数据:

             静态成员变量存储的是所有对象共享的数据

       非静态成员变量存储的是每个对象特有的数据

      B.存储的位置:

       静态成员变量是随着类的加载就在方法区中的静态区中开辟了内存

       非静态成员变量是随着对象的创建在堆中开辟内存

      C.调用方式:

       静态成员变量可以通过类名直接访问,也可以通过对象访问。

       非静态成员变量只能通过对象访问

      D.生命周期:

       静态成员变量随着类的加载就在方法区的静态区出现,整个程序执行完才消失(占用内存比较长,也是其缺点)

       静态成员变量随着对象的创建在堆中出现,随着对象被垃圾回收而消失

    (3)修饰成员变量,成员函数

      A.什么时候把成员变量修饰为static?

        当成员变量被类的所有对象共用时

      B.什么时候把成员函数修饰为static?      

        当静态函数没有用到其所属类的所有非静态成员时

    class Student {
        String name;//实例成员变量
        static String country = "CN";//类变量
        
        //非静态方法既可以使用静态变量,也可以使用非静态变量
        public void show(){//实例成员函数
            System.out.print(name+"----"+country);
        }
        
        //静态方法只能使用静态变量
        public static void fun(){//类方法
             
          //System.out.print(country);//无法从静态上下文中引用非静态变量name
          System.out.print(country);//可以从静态上下文中引用静态变量country
         } 
    }
    
    public class Person { public static void main(String[] args) {
     // TODO Auto-generated method stub 
      Student student = new Student(); 
      student.name = "王涛"; 
      student.show();
      
      Student student1 = new Student(); 
       student1.name = "萧泰"; 
        student1.fun(); 
      }
    }

      运行结果:

      王涛----CN

      萧泰----CNCN

      分析一下为何在静态方法中只能用静态变量:

          fun()是个静态方法,name是非静态变量,需要在对象创建的时候才分配内存,而fun(),country在类加载的时候就分配内存存在了,此时使用name,name不存在。所以在静态方法中只能使用静态变量。

    3.main函数

    public class Person {
    	/**
    	 * main:一个函数,被JVM识别,程序运行的入口
    	 * public:修饰符
    	 * @param args:一个字符串函数类型的参数,其值由JVM传递
    	 * static:静态,随着类的加载在内存静态方法区开辟内存
    	 * void:无返回值
    	 * 
    	 */
    	public static void main(String[] args) {
    		System.out.print(args);
    		System.out.print("---"+args.length);
    		Student student = new Student();
    		
    	}
    

      运行结果:

        [Ljava.lang.String;@5f4fcc96---0

    [:代表一维数组,[[:代表二维数组,java.lang.String:代表String类型,L:代表对象

    4.final

      (1)修饰类,这个类不能被继承。

      (2)修饰方法,这个方法不能被重写

      (3) 修饰变量(局部变量,成员变量),此变量就是一个常量,一旦初始化,就不能再被赋值

     1 //TestA被final修饰,不能再被继承
     2   final class TestA{}
     3 
     4   //TestB继承TestA,会报错
     5   class TestB extends TestA{}
     6 
     7   //TestC被final修饰,不能再被继承
     8   class TestC{
     9     //show被final修饰,不能被重写
    10     public final void show(){}
    11   }
    12 
    13   //TestD继承TestA,会报错
    14   class TestD extends TestC{
    15     public final void show(){
    16       //此处报错
    17     }
    18   }
    19 
    20 
    21   public class Test {
    22     final int a = 1;
    23     //a = 2; 全局变量已被赋值为1,不能再被赋值
    24 
    25     public static void main(String[] args) {
    26 
    27 
    28     }
    29 
    30   }
  • 相关阅读:
    ASP标准控件的重要性
    jndi的疑惑 转
    jms中topic和queue的区别
    JNDI解析
    javascript document 对象属性(转)
    SAX解析xml全解
    java路径解析
    深度学习之美(张玉宏)——第三章 机器学习三重门
    centos7 源码编译安装 php
    centos7 源码编译安装 nginx
  • 原文地址:https://www.cnblogs.com/langdon/p/6292102.html
Copyright © 2011-2022 走看看