1、创建对象----类名 变量名 = new 类名()。
通过对象可以访问其属性和方法
① 首先Student先被编译,class加载到方法区中,类信息也会被初始化出来。
② 执行第7行代码,先执行=号右边的【new Student()】,在堆内存中开辟一块内存空间,这块内存空间会有一个唯一的内存地址,这边假设是0x12340,用于存放new出来的Student实例对象。
这个对象是根据类Student这个模板生成的,所以里面会包含name/age/type这几个属性(name/age模板里面没有赋值,所以使用默认值,type有赋值为1)。
接着把内存地址赋值给=号左边的变量student1,这时候我们就可以通过student1保存的内存地址找到对应堆内存中的Student实例对象。
③ 执行第八行代码,步骤和②一样。要注意的是,这边的【new Student()】会在堆内存里面开辟一块新的内存空间,会有一个自己的内存地址值0x12341赋值给变量student2。
④ 执行第10,11行代码,得到结果都是null。因为此时,student1/student2对应的对象的name还是默认值null。
⑤ 执行13行代码,这时候根据student1保存的内存地址就可以找到堆内存中对应的Student对象,然后把name属性重新赋值成”张三“。
⑥ 执行14行代码,这时候根据student2保存的内存地址就可以找到堆内存中对应的Student对象,然后把name属性重新赋值成”李四“。
⑦ 执行16,17行代码,得到结果分别是【张三】【李四】。由此可以得出结论,堆中的每一个数据都是隔离的,互相不会影响。
⑧ 执行19,20行代码,都是去方法区找Student类型里面的study()方法,然后执行。最后结果都是【好好学习!!】
局部变量:
-
定义:局部变量是定义在方法中或者语句块中。
-
作用范围:只限于所定义的大括号中。
-
成员变量:
-
定义:定义在类中,也可以叫类的属性。
-
作用范围:根据权限的修饰符(public private protected default)。
重载
定义:在同一个类中,方法的名字一样,参数列表不一样(包括参数类型)的两个方法是重载关系,跟返回值没有关系。
目的:为了节约方法的功能命名和提高代码的可读性
this只能在对象方法内使用。
对于类的对象来说,属性是每一个对象都有一份的,是数据隔离的,但是方法是多个数据共享的。不同对象调用这个方法的时候,是用this来区分不同对象的数据,this是可以隐藏的
构造器
用于创建对象的方法,固定格式,给对象赋初始值。
我们使用new的时候相当于调用了类里面的构造器方法。
构造器本身是一个方法。
语法:
-
没有返回值,没有void
-
构造器的方法名必须和类型一致
-
在方法中要定义要初始的参数列表(非必须)
注意点:
-
如果一个类存在有参构造器,那么默认的构造器就会被覆盖,如果需要默认的构造器,就要显示的定义。
-
同一个类中的构造器可以互相调用,需用通过this()来调用,this()必须在第一行。
-
在构造器中调用其他构造器,不会创建对象,只初始化。
static关键字
可以一句话来概括:方便在没有创建对象的情况下来进行调用。
被static关键字修饰的不需要创建对象去调用,直接根据类名就可以去访问。
static一般用来修饰成员变量或函数。
修饰成员变量
被static修饰的成员变量叫做静态变量,也叫做类变量,说明这个变量是属于这个类的,而不是属于对象,没有被static修饰的成员变量叫做实例变量,说明这个变量是属于某个具体的对象的。
public class Student {
public String name; //属于对象 public static String sex; //属于类 public static void main(String[] args) { Student student1 = new Student(); student1.name = "张三"; student1.sex = "男"; Student student2 = new Student(); student2.name = "李四"; student2.sex = "女"; // 获取的name不一样,因为name属性是普通的成员变量,属于对象,每个对象都有自己的name数据 System.out.println(student1.name); // 张三 System.out.println(student2.name); // 李四 // 获取的sex不一样,因为sex属性是static修饰的成员变量,属于类,所有的对象共用 System.out.println(student1.sex); // 女 System.out.println(student2.sex); // 女 // staitc修饰的成员变量可以直接通过【类名.属性名】获取 System.out.println(Student.sex); // 女 // 编译报错 System.out.println(Student.name); }
}
Student.class加载到方法区的时候,系统会自动把Student所有的静态属性和方法分配到静态区,所以我们不需要new对象就可以直接使用Student.sex访问到sex属性。
而我们访问Student.name的时候会编译报错,因为name属性是在new对象的时候,在堆内存里面开辟一块新空间才生成的,所以我们需要先new一个对象,然后通过这个对象访问到自己的name属性。
public class Student {
public void study() { System.out.println("好好学习!!"); } public static void coding() { System.out.println("摩擦键盘!!"); } public static void main(String[] args) { Student student = new Student(); // 对象可以正常调用static修饰的方法和非static修饰的方法 student.coding(); // 可以运行 student.study(); // 可以运行 // static修饰的方法还可以直接通过【类名.方法名】调用 Student.coding(); // 可以运行 Student.study(); // 编译报错 }
}
注意事项
-
静态方法只能访问静态成员(静态成员即静态成员变量和静态方法)。
-
静态方法中不可以使用this或者super关键字。
public class Student { public String name; public static String sex; public void study() { System.out.println(name + "好好学习!!"); System.out.println(sex); } public static void coding() { System.out.println(sex); // 可以访问 System.out.println(name + "摩擦键盘!!"); // 编译报错 study(); // 编译报错(如果study方法改成static修饰,那就可以访问) System.out.println(this); // 编译报错 } }
静态代码块
语法:
class A { // 静态代码块 static { } }
-
static静态代码块只在类加载时执行一次,经常用于初始化资源。
-
静态代码块在main之前执行。