面向对象-this和静态

this

在java语言中规定使用this关键字来代表本类对象的引用。代表当前对象所在函数所属对象的引用。this关键字被隐式地用于引用对象的成员变量和方法中。
this的应用:
1.当成员变量与局部变量同名时,可以用this关键字来区分。
例如在某个函数中参数的名称与函数所属类的成员变量名相同,可以用this.成员变量名 来代表当前本类对象的引用。
哪个对象调用了this所在的函数,this就代表哪个对象。

class Person{
    private String name;
    private int age;
    Person(String name)
    {
        this.name=name;//参数名和成员变量名相同
    }
    public void speak()
    {
        System.out.print(name+":"+age);//speak函数中没有name和age变量,所以访问的是堆里面的成员变量。
    }
}

class ThisDemo{
    public static void main(String[] args){
        Person p=new Person("wangwang");
        p.speak();
    }
}

2.构造函数中调用其他构造函数。
在一个类中,若是有多个构造函数,可以通过this关键字在构造函数中调用其他构造函数,来对当前的对象进行分步的初始化,减少代码量。

Person(){
    name="qiqi";
    age=10;
}
Person(String name){
    this.name=name;
}
Person(String name,int age){
    this(name);//调用第二个构造函数的name来初始化当前对象的name
    this.age=age;
}

为什么不直接用对象的引用名在第三个构造函数中来初始化name呢?
一个类中的成员想要被执行,就必须要有对象的调用,而构造函数在执行前,对象并未初始化,对象的引用还未明确。当前构造函数进入栈内存的时候,会在栈内存中的构造函数中生成一个隐式的this引用变量,来记录当前这个构造函数是被哪一个对象调用。所以此时只能用this(name)而不是Person(name)。
注意:
1.this语句必须在构造函数的第一行。
2.构造函数间不能用this来互相调用,否则会导致死循环。

static关键字

static 的特点:
1.是一个修饰符,用于修饰成员(变量和方法);
2.static修饰的成员被所有的对象所共享;
3.static优先于对象存在,因为static成员是随着类的加载就已经存在了;
4.static修饰的成员多了一种调用方式,就是可以被类名调用:类名.静态成员;
5.static修饰的数据是共享数据,对象中存储的数据是特有数据;
成员变量和静态变量的区别:
1.生命周期不一样;
成员变量是随着对象的创建而存在的,随对象被回收而释放;静态变量随着类的加载而存在,随着类的消失而消失。(一般来说类不会被回收,当虚拟机结束的时候类才会消失,但是如果类特别多而虚拟机在运行状态,java的垃圾回收机制也会启动来回收类。)
2.调用方式不一样;
成员变量只能被对象调用;静态变量不仅可以被对象调用,还可以被类名调用。(推荐类名调用,这样便不用创建新的对象,浪费内存。)
3.别名不同;
成员变量在实例对象中又叫实例变量;静态变量由于可以直接被类名调用,因此也叫类变量。
4.数据存储位置不同。
成员变量数据存储在堆内存的对象里,所以也叫对象的特有数据;静态变量数据存储在方法区(共享数据区)里的静态区里,所以也叫对象的共享数据。

注意:
1.静态方法不可以访问非静态的成员,这是因为静态方法在类创建时就存在了,而此时对象还未创建,非静态的成员存在于对象中,此时还不存在。
同理推,静态的方法可以访问静态的成员,非静态的方法可以访问静态的成员以及非静态的成员。
2.静态方法中不能使用this或者super关键字(理由同上,对象此时还未创建。)
3.主函数是静态的。

主函数

主函数的格式:

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

主函数的特殊之处:
1.格式固定;
2.被java虚拟机(JVM)识别和调用;

public :因为权限必须是最大的;
static :虚拟机调用主函数的时候不需要对象,直接用主函数所属类名调用即可,因此必须定义为静态的;
void :主函数没有具体返回值,因为不需要返回具体值给JVM;
main :函数名,不是关键字,只是JVM识别的固定名字;
String[] args:主函数的参数列表,是一个数组类型的参数,而且数组内的元素都是字符串类型。

class MainDemo{
    public static void main(String[] args){
        System.out.println(args);
        System.out.println(args.length);
    }
}//输出:[Ljava.lang.String;@c17164
 //输出:0

第一行输出@右边的值表示参数所在的哈希值;@左边“[”表示参数是数组类型,“L”表示对象类型,java.lang.String;表示字符串。
0表示参数数组的长度为0。
所以说明JVM调用主函数时往主函数里传递了new String[0]这个参数。
为什么是参数数组的的元素类型是字符串类型的?这是由于字符串是最通用的数据类型。
在dos窗口中运行类名时,在类名后输入内容:
java MainDemo miaomiao wangwang gaga
这样运行出来的参数长度args.length=3
这是因为 JVM看到类名后面有内容,会把这些内容以空格分隔开作为数组中的元素进行封装,然后再把这个数组传递给args,并带着元素的内容。
args只是一个参数名,可以改成x,arguments等,是主函数格式中唯一改变的地方。
static关键字的用处:
1.静态变量:
当分析对象所具备的成员变量相同时,这个对象就可以被静态修饰。
2.静态函数:
该函数是否有访问到对象的特有数据,即该函数是否需要访问非静态的成员变量。如果需要,则非静态,如果不需要,则用静态修饰,虽然此时也可以定义为非静态的,但是非静态的成员需要被对象调用,而仅创建对象去调用非静态的没有访问特定数据的方法,该对象的创建没有意义,而定义为静态的方法可以直接通过类名来直接调用。(对象用于封装特有数据,没有访问特有数据的,创建对象会浪费内存。)

静态代码块:

静态代码块随着类的加载而执行。而且只执行一次。
作用:用于给类进行初始化。(不是所有类都通过构造函数来进行初始化的,因为有些累不需要创建对象就能使用里面的内容。)
构造代码块:
在类中的代码块,可以给所有对象进行初始化(构造函数是给对应的对象进行针对性的初始化),创建几个对象就执行几次。构造代码块可以给所有对象的共有特性进行初始化,其他的特有的属性可以通过构造函数再进行初始化。
局部代码块:
在函数中的代码块,用于限定代码块里面代码的生存周期。

静态代码块最先执行,其次是构造代码块,最后才是局部代码块。

class StaticCode
{//类里面全都是静态成员,可以用静态代码块来对类进行初始化
    static int num;
    static //静态代码块
    {
        num=10;//还可以对num进行一系列运算,如果直接在声明的时候就初始化,那这个值就无法运算来改变。
        System.out.println("miao~"+num);
    }
    static void show()
    {
        System.out.println("show maomao");
    }
}
class StaticCodeDemo
{
    static
    {
        System.out.println("先于main函数的代码块执行");//因为StaticCodeDemo类一加载这个静态代码块就执行了
    }
    public static void main(String[] args)
    {
        StaticCode.show();
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值