java学习(九)static和this使用

java学习(九)static和this使用

static:翻译为静态

  • 所有static关键词修饰的都是类相关的,不需要new对象,都是采用类名.的形式访问,不会出现空指针异常

  • static修饰的方法称为静态方法,static修饰的变量称为静态变量

复习变量(引出静态变量)

  • 方法体内声明的变量叫局部变量

  • 方法体外声明的变量叫成员变量

    • 成员变量可以分为静态变量和实例变量,在实例变量前加static关键词就是静态变量了

静态代码块

  • 静态代码块在类加载时执行,并且只执行一次。 静态代码块实际上是 java 语言为程序员准备的一个特殊的时刻,这个时刻就 是类加载时刻。静态代码块会在main方法之前执行。

静态代码块:

public class StaticTest01{
​
    //静态代码块
    static{
        System.out.println(111);  //先执行
    }
​
    public static void main(String[] args) 
    {
        System.out.println("main 执行!");  //最后执行
    }
​
    //静态代码块
    static{
        System.out.println(222);  //然后执行
    }
}
//静态代码块先执行,然后才是方法执行
  • 可以得知:静态代码块是在main方法之前执行的,是因为静态代码块在类加载时执行,并且只执行一次。

访问静态变量和实例变量

public class StaticTest02{
    
    //实例变量
    int i = 100;
​
    //静态变量
    static int j = 111;
    
    static{
    
        System.out.println(i);  //java:11: 错误: 无法从静态上下文中引用非静态 变量 i
​
        System.out.println(j);  //编译成功
    }
​
    public static void main(String[] args){
        System.out.println("Hello World!");
    }
}

静态属性

  • 当一个类的某个属性值不会随着对象的改变而变化的时候,建议将该属性定义为静态属性。

  • 静态变量在类加载的时候初始化,存储在方法区当中,不需要创建对象,直接通过类名访问

静态方法

  • 在实际的开发中,“工具类”当中的方法一般定义为静态方法,因为工具类就是为 了方便大家的使用,将方法定义为静态方法,比较方便调用,不需要创建对象,直接使用类名 就可以访问。

  • 当某个动作 在触发的时候需要对象的参与,这个方法应该定义为实例方法

java中的this是什么,内存中存储在哪里,要掌握 this 在实例方法和构造方法中的 用法。

  • this 可以看做一个变量,它是一个“引用”,存储在 Java 虚拟机堆内存的对象内部,this 这个“引用”保存了当前对象的内存地址指向自身,任何一个堆内存的 java 对象都有一个 this 。

  • this 指向“当前对象”,也可以说 this 代表“当前对象”,this 可以使用在实例方法中以及 构造方法中,语法格式分别为“this.”和“this(..)”。this 不能出现在带有 static 的方法当中。

public class ThisInStaticMethod{
​
    public static void main(String[] args) {
​
        ThisInStaticMethod.method();
    }
    public static void method(){
​
        System.out.println("method执行");
        System.out.println(this);  //java:11: 错误: 无法从静态上下文中引用非静态 变量 this
​
    }
}
​

得知:this不能出现在 static的方法当中,static 方法执行的过程中是不需要“当前对象”参与的,所以 static 的方法中不能使用 this,因为 this 代表的 就是“当前对象”。

this:this只能在实例方法中使用,谁调用这个实例方法,this就是谁,就是指当前对象!

public class Customer{
​
    private String name;
​
    //无参构造方法
    public Customer(){
    }
​
    //有参构造方法
    public Customer(String _name){
        name = _name;  //这里的name就是实例变量neme,_name是接收的局部变量
    }
    
    //set
    public void setName(String _name){
        name = _name;
    }
​
    //get
    public String getName(){
        return name;
    }
​
    //定义一个实例方法
    public void shopping(){
        System.out.println(this.name + "is shopping!");  //谁调用就打印谁
        System.out.println(name + "is shopping!");  //谁调用就打印谁
    }
}

调用:

public class CustomerThisTest{
​
    public static void main(String[] args) {
​
        CustomerThis jack = new CustomerThis("jack");
​
        jack.shopping();  
​
        System.out.println("分界线===============================");
​
        CustomerThis rose = new CustomerThis("rose");
​
        rose.shopping(); 
    }
}

得 知 :在实例方法中可以 直接访问当前对象的实例变量,而“this.”是可以省略的。

那么this在什么时候不能省略?

当接收的局部变量参数和实例变量相同的时候,例:name = name;需要写成this.name = name这里的this就不可以省略了哈哈哈哈。【否则name = name这两个name都会被识别成局部变量哦】

  • 访问实例变量,实例方法。上面Customer代码块修改:

    //定义一个实例方法
    public void shopping(){
    
        System.out.println(name + "is shopping!");  //谁调用就打印谁
        System.out.println(this.name + "is shopping!");  //谁调用就打印谁
​
        this.pay();
        
        //省略this
        pay();
    }
​
    //再定义一个实例方法
    public void pay(){
        System.out.println(name + "付钱付钱");
    }
}
            /*
            jackis shopping!
            jackis shopping!
            jack付钱付钱
            jack付钱付钱
            分界线===============================
            roseis shopping!
            roseis shopping!
            rose付钱付钱
            rose付钱付钱
            */

得出:在一个实例方法当中可以直接去访问其它的实例方法

代码

public class ThisTest {
​
    int i = 10;
​
    public static void main(String[] args) {
​
        //System.out.println(i);  //错误: 无法从静态上下文中引用非静态 变量 i。因为main方法有static,i是实例变量,要用引用.去访问
​
        //System.out.println(this.i); // 错误: 无法从静态上下文中引用非静态 变量 this。因为 main 方法带有 static,不能用 this(代表当前对象)
​
        ThisTest tt = new ThisTest();
​
        //通过引用访问
        System.out.println(tt.i);
    }
}

得知:

  • 在 static 的方法中不能直接访问实例变量,须先自己创建一个对象,通过“引用”可以去访问。

  • 在 static 的方法中不能通过 this 访问实例变量,因为在 static 方 法中是不能存在 this 的。

同理:

  • main 方法中无法直接调用实例方法 ,因为实例方法也必须要new对象,通过引用调用

this 使用在构造方法中,this(实际参数列表);调用另一个有参的构造方法

  • this();语法要在同一个类中使用

  • this();只能在构造方法第一行,前面不能有其他代码

public class ThisTest02{
    public static void main(String[] args){
​
        //调用无参构造
        Date d1 =  new Date();
        d1.detail();
        
        //调用有参构造
        Date d2 = new Date(2020,06,19);
        d2.detail();
    }
}
​
    
class Date{
    private int year;
​
    private int month;
​
    private int day;
​
​
​
    //业务要求,默认创建的日期为 1970 年 1 月 1 日
    //无参构造方法
    public Date(){
        /*
        this.year = 1970;
        this.month = 1;
        this.day = 1;
        */
        //System.out.println("随便写一行代码在this()前");  //错误: 对this的调用必须是构造器中的第一个语句
​
        //无参构造方法调用有参构造方法1行代码
        this(1970,1,1);  
    }
​
    //有参构造方法
    public Date(int year,int month,int day){
        this.year = year;
        this.month = month;
        this.day = day;
    }
​
    //定义一个打印年龄的方法
    public void detail(){
        System.out.println(year + "年" + month +"月" + day + "日");
    }
​
    //set和get
    public void setYear(int year){
        this.year = year;
    }
    
    public int getYear(){
        return year;
    }
​
    public void setMonth(int month){
        this.month = month;
    }
​
    public int getMonth(){
        return month;
    }
​
    public void setDay(int day){
        this.day = day;
    }
    
    public int getDay(){
        return day;
    }
}

小总结:

  • 代码封装,属性一般都私有化

  • 都要有两个构造方法,一个无参构造,一个有参构造。(对象属性的 初始化)

  • 都要有对应的set和get方法,这是封装的规定,就算暂时用不到也要写。

  • 封装的get方法要指定返回值的类型,不需要传参。

  • 封装的set方法不需要返回值,所以返回值类型固定写法void,但是需要传参数。

  • 只要调用的方法a和被调用的方法b是在同一个类里面,this.和类名.可以省略

银行存取款代码:其实这3个类写入3个文件内比较好

public class TestCustomerAccount{
​
    public static void main(String[] args){
        
        Account a = new Account("10086",1000,0.0023);
​
        Customer c = new Customer("smth",a);
​
        //存100
        //取960
        //取200
​
        c.getAct().deposite(100);
        c.getAct().withdrow(960);
        c.getAct().withdrow(2000);
        
    }
}
​
//客户类
class Customer{
​
    private String name;
    
    private Account act;
​
​
    //构造方法
    public Customer(){
    
    }
    
    //有参构造
    public Customer(String name,Account act){
        
        this.name = name;
​
        this.act = act;
    }
    
​
    //set 和 get方法
​
    public void setName(String name){
    
        this.name = name;
    }
​
    public String getName(){
​
        return name;
    }
​
    public void setAct(Account act){
​
        this.act = act;
    }
​
    public Account getAct(){
        return act;
    }
}
​
//账号类
class Account{
    private String id;  
    private double balance;  //余额实例属性
    private double annualInterestRate;   //年利率实例属性
​
        
    //无参构造
    public Account(){
    
        
    }
    
    //有参构造,
    public Account(String id, double balance, double annualInterestRate){
​
        //构造方法是创建对象的时候,对象的属性初始化
        this.id = id;
        this.balance = balance;
        this.annualInterestRate = annualInterestRate;
    }
​
​
    //各属性set和get,这里是后期查询和修改需要
    //为啥每个类都写set和get方法,用不到也要写,因为这是“封装”的规定
    public String getId(){
        return id;
    }
​
    public void setId(String id){
        this.id = id;
    }
​
    public double getBalance(){
        return balance;
    }
​
    public void setBalance(double balance){
        this.balance = balance;
    }
​
    public double getAnnualInterestRate(){
        return annualInterestRate;
    }
​
    public void setAnnualInterestRate(double annualInterestRate){
        this.annualInterestRate = annualInterestRate;
    }
    
    
    //存钱方法
    //存钱要传一个参数告诉存多少钱
    
    public void deposite(double money){
    
        //this.balance += money;
        
        this.setBalance(this.getBalance() + money);
        System.out.println("存款成功" + money);
        
    }
​
​
    //取钱方法
    //取钱需要传一个参数告诉取多少钱
    public void withdrow(double money){
        if(money > this.getBalance()){
            System.out.println("余额不足,取款失败");
            return;
        }
        this.setBalance(this.getBalance() - money);
        System.out.println("取款成功"+ money);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值