匿名对象
匿名对象就是没有名字的对象,只在堆内存中开辟空间,而不存在栈内存的引用。
//普通对象调用方法
Student s=new Student();
method(s);
//匿名对象调用方法
//将对象的地址值和方法method的形参s关联
method(new Student());
//定义方法
public void method(Student s){
}
普通对象和匿名对象的区别
1、普通对象;在堆中创建:Student stu=new Student()
普通对象的销毁:stu在main方法中声明,等main方法出栈后,对象的引用stu在栈内存中
消失。此时堆内存的地址值就和main方法没有关系,jvm将其标记为垃圾数据。
2、匿名对象的创建:method(new Student());
method方法出栈后,匿名对象就会被标记为垃圾数据。这样更早的会被垃圾扫描器清除,提高内存的使用率
匿名对象弊端:只能使用唯一的一次
类中的私有方法
private修饰的方法称为私有方法
私有方法特点:只能在本类中进行访问。(区分本类和当前类,在内部类)
应用场景:类中多个方法存在共性内容时,可以将多个方法的共性内容抽取为私有化方法(不对外界提供)
构造器代码块
所处位置:类中方法外
当类中所有构造器存在相同代码时,可以将这些相同代码提取到构造器代码块
注意:
1、构造器代码块是由构造器中的第二部分隐式代码隐式调用。因此可以说,构造器代码块不是优先于构造器调用,但可以说优先于构造器中显示代码调用。
2、静态代码块是随着类的加载而加载,而构造代码块和构造方法都是随着对象的创建而加载。
this关键字第二种用法
场景使用:部分构造器有相同的代码
this(实参): 出现在(子)类构造器中,调用类中其他构造器完成初始化工作。
public class Teacher {
private String name;
private int age;
public Teacher() {
this(1);
System.out.println("无参构造器");
}
public Teacher(int i) {
this(1,2);
System.out.println("1个参数构造器");
}
public Teacher(int i,int j) {
//控制台打印的唯一一个构造器代码块是这里的隐式代码
System.out.println("2个参数构造器");
}
{
System.out.println("构造器代码块");
}
}
测试类调用:
public static void main(String[] args) { new Teacher(); }
运行结果:这结果跟我想的一样哈
static 静态的、共享的
格式:修饰符 static 数据类型 变量名;
用来修饰:成员量(常量和变量)、成员方法、代码块,成员内部类
1.被static修饰的内容不再属于对象,会归属于类,被这个类所创建的对象共享
2.被static修饰的内容随着类的加载而加载。主要指类文件(字节码对象)的加载而加载而且字节码只加载一次,static修饰的内容也只加载一次.
static变量
调用:类名.静态变量名(推荐);也可以对象名.静态变量名(不推荐)
在方法区中有:
字节码文件区:用来存储字节码文件对象
静态变量区:有默认值(因为方法区归属于堆)
静态区里有jvm监视器,用来检测main方法有没有进入静态区。监视器通过jvm调用main方法,main方法进栈。
学生学号id自增的功能
public class Student {
//学生学号id自增的功能
static int num=220411001;
//构造器代码块
{
this.id=num++;
}
private int id;
private String name;
private int age;
public Student() {
}
public Student(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public void study() {
System.out.println(id+" :学生-"+name+":"+age+"岁");
}
}
测试类:
public class Demo {
public static void main(String[] args) {
Student s1 = new Student("乱古大帝",13);
Student s2 = new Student("无终大帝",15);
Student s3 = new Student("弃天大帝",17);
s1.study();
s2.study();
s3.study();
Student s4 = new Student();
s4.setName("荒天帝");
s4.setAge(9);
s4.study();
}
}
运行结果:
第一个是001是因为,num是静态变量在类加载的时候就执行了初始化为220411001
在main方法中创建对象的时候,构造器代码块属于第二部分“隐式实例初始化”部分,所有会让构造器代码块中this.id=num++;先赋值再加加。那么这是id便是220411001
static方法
1.被static修饰的方法不再属于对象,而是归属于类,会被这个类创建的所有对象所共享。
静态区不管用不用都已经创建好了,而new对象的话却需要开辟堆内存空间。
为了防止对象强制创建,需要对构造器私有化。比如类MATH,Arrays 他们的构造器私有化,里面方法全部都是static方法。
2.静态方法随着类的加载而加载,这里的加载指静态方法进入静态区且只加载唯一的一次。
而静态方法的调用则需要进入栈内存,方法不调用不执行。
3.静态方法中不可以使用this关键字。
4.静态方法中调用成员关系:
实例方法中调用非静态成员:成立
实例方法中调用静态成员:成立
静态方法中调用静态成员:成立
静态方法中调用非静态成员:不成立
面试题:为什么静态方法中调用非静态成员不成立
这是因为,对于非静态的方法和变量,需要先创建类的实例对象后才可使用,而静态方法在使用前
不用创建任何对象。
static代码块
当类被载入时,自动执行静态代码块,且只被执行一次,经常用于类变量的初始化。
//位置:类中方法外
static{
System.out.println("静态代码块");//静态代码块只加载一次
}
作用:
1.用来提高对象的加载时机,封装高级工具类。(jdbc封装工具类)
2.在类的初始化过程面试题中会出现
3.给静态常量进行初始化赋值要注意的:
1.静态代码块随着类的加载而加载,且只加载唯一的一次。
2.静态代码块中无法使用非静态成员。
3.静态代码块中无法使用this关键字。