IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> this和static关键字 -> 正文阅读

[Java知识库]this和static关键字

1.this关键字

1) this关键字在内存中的位置

先看一段代码

public class Customer {
	private String name;
	public Customer(){
	}
	public Customer(String _name){
		name = _name;
	}
	public void setName(String _name){
		name = _name;
	}
	public String getName(){
		return name;
	}
}
public class CustomerTest {
	public static void main(String[] args) {
		Customer jack = new Customer("jack");
	}
}

以上代码在内存中的活动图为(16进制以0x开头,2进制以0b开头,8进制以0开头)

在这里插入图片描述

在图中可以看出,this是一个引用,它存储在Java虚拟机堆内存的对象内部,this这个引用保存了当前对象的内存地址,指向自身。任何一个堆内存的Java对象都有一个this。即this代表当前对象,this可以使用在实例方法和构造方法中,this不能出现在带有static的方法中。

2) this在实例方法和实例变量中的使用

  1. static的方法中不能使用this

    被static修饰的方法称为静态方法,静态方法调用时使用-类名.方法名-调用,不需要创建对象,而this关键字代表的是当前对象,此处冲突。

    为什么set、get方法设计为实例方法呢?(不被static修饰)

    因为set、get方法操作的是实例变量,"不同对象"调用get方法得到的数据是不同的,强调的是对象,显然调用该方法不能用类名.方法名调用,必须先创建对象,再通过引用去访问

  2. this可以出现在实例方法中,它指向当前调用这个方法的对象

    因为通过对象名.方法名调用实例方法,此时一定会提前创建对象,用对象去触发实例方法,实例方法一定要对象才可以调用,而恰好this关键字又代表当前对象,存储在Java虚拟机堆内存的对象内部,即对象的内部。

  3. 在实例方法中可以直接访问当前对象的实例变量,而this是可以省略的,而在set、get方法中的不能省略。

    public class Customer{
        private String name;
        public Customer(String name){
            this.name=name;
        }
        public void setName(String name){
            this.name=name;
    //this.name代表的是实例变量,而那么、代表的是局部变量,如果this省略根据就近原则,省略this后的name为局部变量
        }
        public String getName(){
            return this.name;
        }
        public voif shopping(){
            System.out.println(name);
            System.out.println(this.name);
        }
            
    }
    public class Test{
        public static void main(String[] args){
            Customer c=new Customer("jack");
            c.shopping();
        }
    }
    
    //输出的结果是
    jack
    jack
    

从以上代码可知,name和this.name输出的结果是想等的。即当实例方法中要访问实例变量时,可直接通过实例变量名来访问,也可以使用"this."来访问,也就是说在实例方法中访问实例变量时"this."可以省略

  1. 在一个实例方法中可以直接调用其他的实例方法("this."省略),也可以使用this.方法名调用,相当于对象.方法名.

    public class Customer{
        private String name;
        public Customer(String name){
            this.name=name;
        }
        public void setName(String name){
            this.name=name;
        }
        public String getName(){
            return this.name;
        }
        public void shopping(){
            System.out.println(name);
            System.out.println(this.name);
            System.out.println("调用其他的实例方法"+this.pay());
              System.out.println("调用其他的实例方法"+pay());
        }
        public void pay(){
            System.out.println("支付方法");
        }
            
    }
    public class Test{
        public static void main(String[] args){
            Customer c=new Customer("jack");
            c.shopping();
        }
    }
    
  2. 在main方法中无法直接访问实例方法和实例变量

    实例方法要通过对象.方法名或变量名调用(通过引用去访问),而main方法为static类型的,属于类,在类加载的时候执行。在执行main方法时,如对象还没有被创建,所以就还没有"this",因为"this"代表当前对象,没有对象所以不能用this,也就不能直接访问实例方法或变量 。

    public class Test{
        public void M(){
            System.out.println("实例方法");
        }
        public static void main(String[] args){
          M();//次数出现编译错误,因为不能直接使用实例方法
          new Test().M();//正确调用
        }
    }
    
    
    
    
    
    public class Test{
        int i=10;
        public static void main(String[] args){
          System.out.println(i);//次数出现编译错误,因为不能直接使用实例变量
          System.out.println(new Test().i);//正确调用
        }
    }
    

3) this在构造方法中的使用

  1. 在构造方法中的第一行,用来调用本类中其他的构造方法

    public class Customer{
        private String name;
        public Customer(){
            this("jack");
        }
        public Customer(String name){
            this.name=name;
        }
    }
    //根据this()的括号中传入的参数来选择相应的构造方法
    //this(实际参数列表);
    

2.static关键字

1) static介绍

  1. static 表示静态的,属于类,随着类的加载而加载,优先于对象存在
  2. 可以修饰方法、变量、代码块等,修饰的可以在它所在的类创建对象之前被访问。修饰的方法称为静态方法,修饰的变量称为静态变量,修饰的代码块称为静态代码块

2)静态变量

java中的变量分为局部变量、成员变量(实例变量)和类变量(静态变量)。局部变量存在于栈中,成员变量(实例变量)存在于堆中、静态变量存在于方法区中。实例变量在构造方法执行过程中初始化,静态变量在类加载时初始化。被static修饰的成员变量为静态变量,不需要创建对象就可以被调用(调用方式:类名.变量名)。

(1)变量在什么情况下会声明为静态变量

? 当一个类的所有的对象的某个变量(属性)的值不会随着对象的改变而改变时,可将该变量设定为静态变量(静态属性)

例如:有一个类它的出生年份都是2000年,每个对象的姓名和ID号都不同。

修改前:

class Student {
    private String name;
    private int id;
    private String year;

    public Student() {

    }

    public Student(String name, int id, String year) {
        this.name = name;
        this.id = id;
        this.year = year;
    }

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +'\'' +
                ", year=" + year+
                '}';
    }

    public static void main(String[] args) {
        Student s1=new Student();
        s1.setId(1);
        s1.setName("张三1");
        s1.setYear("2000");
        Student s2=new Student();
        s2.setId(2);
        s2.setName("张三2");
        s2.setYear("2000");
        Student s3=new Student();
        s3.setId(3);
        s3.setName("张三3");
        s3.setYear("2000");
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);
    }
}

修改后:

class Student {
    private String name;
    private int id;
    private  static String year="2000";

    public Student() {

    }

    public Student(String name, int id, String year) {
        this.name = name;
        this.id = id;
        this.year = year;
    }

    public Student(String name, int id) {
        this.name = name;
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getYear() {
        return year;
    }

    public void setYear(String year) {
        this.year = year;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", id=" + id +'\'' +
                ", year=" + Student.year+
                '}';
    }

    public static void main(String[] args) {
        //若将年份设置为静态变量
        Student s1=new Student();
        s1.setId(1);
        s1.setName("张三1");
        Student s2=new Student();
        s2.setId(2);
        s2.setName("张三2");
        Student s3=new Student();
        s3.setId(3);
        s3.setName("张三3");
        System.out.println(s1);
        System.out.println(s2);
        System.out.println(s3);

    }
}

输出的结果均为

Student{name='张三1', id=1', year=2000}
Student{name='张三2', id=2', year=2000}
Student{name='张三3', id=3', year=2000}

(2) 可以用引用来访问静态变量吗?可以的话,这个访问和具体的对象有什么关系?

//使用上一例子的代码
Student s1=new Student();
System.out.println(s1.year);
//输出的结果为2000

可得出:可以用引用来访问静态变量。但实际上,引用所指的对象并没有参与,如果是空引用访问实例变量,那么一定会发生空指针异常,但是以上编译通过了说明实际上并不是通过对象去访问的,而是通过类去访问的。静态变量和静态方法使用“引用”也可以访问,并且空引用访问静态变量和静态方法并不会出现空指针异常。空引用访问实例相关的成员,必然会出现空指针异常。

3)静态代码块

静态代码块在类加载的时候执行,且执行一次。当有多个静态代码块(或者静态代码块和静态变量)同时执行时,执行顺序遵循从上到下依次执行的原则。

class Student {
    static{
        System.out.println(m);//此处会报错因为静态代码块和静态变量同时执行时,执行顺序遵循从上到下依次执行的原则。所以先执行此处的代码,但是执行此处代码时m并没有被定义。
    }
    static int m=0;
    static{
        System.out.println("静态代码块1");
    }

    public static void main(String[] args) {
        System.out.println("main方法");

    }
    static{
        System.out.println("静态代码块2");
    }
}
class Student {
    static int m=0;
    static{
        System.out.println("静态代码块1");
    }
    static{
        System.out.println(m);
    }

    public static void main(String[] args) {
        System.out.println("main方法");

    }
    static{
        System.out.println("静态代码块2");
    }
}
//执行结果
/*
静态代码块1
0
静态代码块2
main方法
*/
class Student {

    static int m=0;
    static{
        System.out.println("静态代码块1");
    }

    static{
        System.out.println(m++);
    }

    public static void main(String[] args) {
        System.out.println("main方法");
        System.out.println(m);
    }
    static{
        System.out.println("静态代码块2");
    }
}
//
/*
静态代码块1
0
静态代码块2
main方法
1
*/

4)静态方法

什么情况下要将方法设置为静态方法?方法描述的是行为,当某一行为不需要对象就可以触发时,可以将该方法设置为静态方法。或者在方法中不需要使用"当前对象"这一概念时,可以设置为静态方法。

5)选择方法是静态的还是非静态的

工具类中的方法为静态方法,使用方法不需要考虑对象,只知道类中的方法可以干我需要的事情时,使用静态方法。这样可以避免不必要的对象的创建

3.this与static相关案例题

小编正在补充中……
在这里插入图片描述

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-29 11:57:31  更:2022-04-29 11:58:10 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 2:11:51-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码