类与对象
类:class,类是对对象的抽象。
对象:object,instance,对象是对客观事物的抽象。
对象是具体的事物;类是对对象的抽象;
对象是类的实例,类是对象的模板。
类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法
Java虚拟机的内存
可以分为三个区域:栈,堆,方法区
栈的特点:
- 栈描述的是方法执行的内存模型。每个方法被调用都会创建一个栈帧(存储局部变量、操作数、方法出口等)
- JVM为每个线程创建一个栈,用于存放该线程执行方法的信息(实际参数、局部变量等)
- 栈属于线程私有,不能实现线程间的共享
- 栈的存储特性是“先进后出,后进先出”
- 栈是由系统自动分配,速度快。栈是一个连续的内存空间
堆的特点:
- 堆用于存储创建好的对象和数组(数组也是对象)
- JVM只有一个堆,被所有线程共享
- 堆是一个不连续的内存空间,分配灵活,速度慢
方法区(又叫静态区)特点:
- JVM只有一个方法区,被所有线程共享
- 方法区实际也是堆,只是用于存储类、常量相关的信息
- 用来存放程序中永远是不变或唯一的内容。(类信息(Class对象)、静态变量、字符串常量等)
类中代码执行顺序
- 先执行静态代码块
- 类中定义静态成员变量对象,会先创建对象;静态代码和静态代码块的执行顺序由它们的位置决定
- 如果是非静态代码块和成员变量,就不执行;只有在创建对象的时候才会执行,创建多少个对象就执行多少次,顺序由位置决定
注:静态代码块从属于类,类加载了它就会执行;非静态代码从属于对象,创建对象它就会执行
构造器
也叫构造方法,用于对象的初始化
要点:
- 通过new关键字调用
- 构造器虽然有返回值,但是不能定义返回值类型(返回值的类型肯定是本类),不能在构造器里使用return返回某个值。
- 如果我们没有定义构造器,则编译器会自动定义一个无参的构造函数。如果已定义则编译器不会自动添加
- 构造器的方法名必须和类名一致
class Point {
double x, y;
//构造方法名称和类名称必须保持一致
public Point(double _x, double _y) {
x = _x;
y = _y;
}
public double getDistance(Point p) {
return Math.sqrt((x - p.x) * (x - p.x) + (y - p.y) * (y - p.y));
}
}
public class TestConstructor {
public static void main(String[] args) {
Point p = new Point(3.0, 4.0); //通过构造器初始化对象
Point origin = new Point(0.0, 0.0);
System.out.println(p.getDistance(origin)); //对象引用方法
}
构造方法重载(创建不同用户对象)
如果方法构造中形参名与属性名相同时,需要使用this关键字区分属性与形参
public class User {
int id; // id
String name; // 账户名
public User() {
}
public User(int id, String name) { //构造方法重载
super();
this.id = id; //this表示当前对象实例 区分成员变量和局部变量
this.name = name; //前一个id是 成员变量的id,后一个id是局部变量的id
}
public static void main(String[] args) {
User u1 = new User();
User u2 = new User(101, "h");
}
}
对象创建的过程和this的本质
创建一个对象分为如下四步
- 分配对象空间,并将对象成员变量初始化为0或空
- 执行属性值的显示初始化
- 执行构造方法
- 返回对象的地址给相关的变量
this的本质就是创建好的对象的地址,由于在构造方法调用前,对象已经创建。因此,在构造方法中也可以使用this代表”当前对象”
this最常的用法
- 使用this来指明当前对象的实例
- 普通方法中,this总是指向调用该方法的对象。构造方法中,this总是指向正要初始化的对象。
- 使用this关键字调用重载的构造方法,避免相同的初始化代码。但只能在构造方法中用,并且必须位于构造方法的第一句。
- this不能用于static方法中(static方法加载在类中,还没有实例化对象)
注:this关键字指”当前对象实例”,然而main方法是静态的,它是程序的入口,在程序编译的时候,它会自动地被JVM加载到内存中。在这个时侯,程序还没有实例化对象,所以,不能在main方法里使用非静态的this了
public class TestConstruct {
int a,b,c; //成员变量
//构造器方法
public TestConstruct(int a,int b) {
this.a = a;
this.b = b;
}
public TestConstruct(int a,int b,int c) {
this(a,b); //构造器的调用 放首行
this.c = c;
}
void eat() {
System.out.println("吃饭");
}
public static void main(String[] args) {
TestConstruct hi =new TestConstruct(2,3);
hi.eat();
}
}
Static
Static修饰的成员变量和方法,从属于类。普通的变量和方法从属于对象
- 为该类的公用变量,属于类,被该类的所有实例共享,在类被载入时被显式初始化
- 对于该类的所有对象来说,static成员变量只有一份。被该类的所有对象共享
- 一般用”类名.类属性/方法”来调用。(也可以通过对象引用或类名(不需要实例化)访问静态成员)
- 在static方法中不可直接访问非static的成员。
参数传值机制
Java中方法中的所有参数都是值传递(值的副本)