创建类
形式:
修饰符 class 类名{
}
public class Person {
//成员变量--放在类中方法外
int age ;
String name;
//类中创建方法
public void eat(){
int num = 10;//局部变量:放在方法中
System.out.println("我喜欢");
}
创建对象
形式(举例):
Person p = new Person();
public class Test {
public static void main(String[] args) {
/**
Person 属于 引用数据类型
初始化创建对象的时候,对象的属性没有给赋值,有默认的初始化的值。
*/
Person zs = new Person();
zs.name = "张三";
zs.age = 19;
/**
再创建一个对象:
再次创建类的时候,就不会进行类的加载了,
类的加载只在第一次需要的时候加载一次
*/
Person ls = new Person();
ls.name = "李四";
ls.age = 18;
//对属性值进行读取:
System.out.println(zs.name);
System.out.println(ls.age);
//对方法进行操作:
//不同的对象,属性有自己的特有的值,但是方法都是调用类中通用的方法。
//属性:各个对象的属性是独立的,
//方法:各个对象的方法是共享的。
zs.eat();
ls.eat();
}
}
对象在内存中的存储
-----------------------------对象在内存中的存储--------------------
java把内存分成5大区域,我们重点关注栈和堆
1.一般来讲局部变量存在栈中,方法执行完毕内存就被释放
2.对象(new出来的东西)存在堆中,对象不在被使用时,内存才会被释放
3.每个堆内存元素都有地址值
4.对象中的属性都有默认值
局部变量和成员变量的区别
区别1:位置不同
成员变量:类中方法外定义的变量
局部变量:方法中定义的变量 代码块中定义的变量
区别2:作用范围不同
成员变量:当前类
局部变量:当前一个方法中(当前代码块中)
区别3:有无默认值
成员变量:有
局部变量:没有
成员变量有默认值:
引用数据类型: null
区别4:是否必须初始化
成员变量:不需要,不建议初始化,后续使用的时候再赋值即可
局部变量:一定需要,不然直接使用的时候报错
区别5:内存中位置不同
成员变量:堆内存
局部变量:栈内存
区别6:作用时间不同
成员变量:当前对象从创建到销毁
局部变量:当前方法从开始执行到执行完毕
构造器(构造方法)
方法名与类名相同
public class Person {
//构造器:没有任何参数的构造器我们叫做:无参构造
public Person(){
}
public Person(String name,int age){//含参构造
//当形参名字和属性名字重名的时候,会出现就近原则:
//在要表示对象的属性前加上this.来修饰,因为this代表的就是你创建的那个对象
this.name = name;
this.age = age;
}
//成员变量
int age ;
String name;
//方法:
public void eat(){
System.out.println("我喜欢吃饭");
}
}
构造方法中的细节:
1.一般要保证无参构造的存在,无参构造中一般不会进行属性的赋值操作
2.一般我们会重载构造器,在重载的构造器中进行属性赋值操作
3.在重载构造器以后,假如空构造器忘写了,系统也不会给你分配默认的空构造器了,那么你要调用的话就会出错了。
4. 当形参名字和属性名字重名的时候,会出现就近原则:
在要表示对象的属性前加上 this. 来修饰 ,因为this代表的就是你创建的那个对象
this关键字的使用总结
一、
局部变量和成员变量同名,
在局部变量中想使用成员变量的那个值
class Office{
int sum = 20;//成员变量
public void eat() {
int sum = 10;//局部变量
System.out.println(sum);//10 使用的是局部变量sum--就近原则
System.out.println(this.sum);//20 通过this.访问了成员变量sum
}
二、
无参构造中调用含参构造
class gen{
public gen() {
无参调用含参时 this要写在第一行且先执行调用的,在执行自己的代码
this("rose");
System.out.println("无参构造-------");
}
三、
含参构造中调用无参构造
public gen(String n) {
this();含参也可以调用无参
System.out.println("含参构造"+n);
}
static关键字的使用细节
static修饰属性总结:
(1)在类加载的时候一起加载入方法区中的静态域中
(2)先于对象存在
(3)访问方式: 对象名.属性名 类名.属性名(推荐)
案例: static修饰属性
public class MsbStudent {
//属性:
String name;
int age;
static String school;
public static void main(String[] args) {
MsbStudent.school = "马士兵教育";
//创建学生对象:
MsbStudent s1 = new MsbStudent();
s1.name = "张三";
s1.age = 19;
//s1.school = "马士兵教育";
//System.out.println(s1.school);
System.out.println(s1.name);
System.out.println(MsbStudent .school);
}
}
案例: static修饰方法
public class Demo {
//定义成员变量
int id;
static int sid;
//定义成员方法
public void a(){
System.out.println(id);
System.out.println(sid);
System.out.println("------a");
}
//1.static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都行
static public void b(){
//System.out.println(this.id);//4.在静态方法中不能使用this关键字
//a();//3.在静态方法中不能访问非静态的方法
//System.out.println(id);//2.在静态方法中不能访问非静态的属性
System.out.println(sid);
System.out.println("------b");
}
//main方法
public static void main(String[] args) {
//5.非静态的方法可以用对象名.方法名去调用
Demo d = new Demo();
d.a();
//6.静态的方法可以用 对象名.方法名去调用
// 也可以 用 类名.方法名 (推荐)
Demo.b();
d.b();
}
}
static修饰方法总结:
(1)static和public都是修饰符,并列的没有先后顺序,先写谁后写谁都行
(2)在静态方法中不能访问非静态的属性
(3)在静态方法中不能访问非静态的方法
(4)在静态方法中不能使用this关键字
(5)非静态的方法可以用 对象名.方法名去调用
(6)静态的方法可以用 对象名.方法名去调用 也可以 用 类名.方法名 (推荐)
之所以那么多不可以,是因为,静态的在没有创建对象时就已经创建了
代码块的执行顺序
1.静态代码块:在类加载时就加载,并且只加载一次,一般用于项目的初始化
2.构造代码块:在创建对象时会自动调用,每次创建都会被调用
3.局部代码块:方法里的代码块,方法不调用就不会执行
总结:
1代码块之间的执行顺序:静态代码块>构造代码块>局部代码块
2.为什么是这样的执行顺序呢?
原因:
1、静态代码块优先于对象加载,是随着类的加载就会第一时间加载进入内存,
并一直存在。专门用来完成一些需要第一时间加载并且只需加载一次。
2、构造代码块是在创建对象时才会触发,专门用来提取构造方法的共性
3、局部代码块是方法调用时才会触发,专门用来控制变量的作用范围
public static void main(String[] args) {
特点1,在创建对象前,会自动执行静态代码块,且只执行一次
特点2,在创建对象时,会自动调用构造代码块和构造方法
person8 p = new person8();
特点3,当调用show()时,才会触发局部代码块
p.show();
person8 p2 = new person8();这次不会加载静态代码块
}
//创建person类
class person8{
静态代码块:位置:类里方法外-触发节点:随着类的加载而加载,且只加载一次
static { System.out.println("静态代码块。。。。。"); }
构造代码块,位置:类里方法外---触发节点:创建对象时
{System.out.println("构造代码块。。。。。");}
public person8() {
System.out.println("构造方法。。。。");
}
局部代码块,----位置:方法里----------触发节点:调用方法时
public void show(){ {System.out.println("局部代码块。。。");} }