一 今日目标
- 构造方法
- static关键字
- 代码块
- math类
- package关键字
- import关键字
二 构造方法概述
2.1 构造方法描述
构造方法是一个特殊方法,作用是创建对象,对对象进行初始化。 如:
对对象中的成员进行初始化值
2.1 构造方法的特征
1、方法名与类名相同 2、 不声明返回值类型(与声明为void不同,不能有void) 3、不能被static、final、synchronized、abstract、native修饰 4、方法上可以定义参数列表,定义参数列表方式与成员方法相同 5、创建对象时执行 6、权限修饰符与成员方法定义一致
2.3 构方法格式
无参数构造方法:
权限修饰符 类名() { 初始化语句; } public class Person { private String name; private int age; // 无参构造器 // 创建Person对象时,会调用构造器,将name初始化为"Tom",将age初始化为10 public Person() { name = "Tom"; age = 10; } }
有参数构造方法:
格式:
权限修饰符 类名(参数列表) { 初始化语句; }
代码实现:
public class Person { private String name; private int age; //有参构造器 public Person(int age,String name) { this.age = age; this.name = name; } }
面试:一个类中成员变量私有后,外部有几种方式对私有变量赋值?
2.4 构造方法与成员方法区别
构造方法 | 成员方法 | |
---|---|---|
作用 | 对对象进行初始化 | 封装现实事物的行为 |
执行 | 创建对象即执行 | 需调用再执行 |
格式 | 没有返回值、方法名和类名相同 | 按照标准的方法定义格式 |
2.5 构造方法重载
2.5.1 构造方法重载描述
构造方法支持重载,在类中可以定义多个参数列表不同的构造方法,在创建对象时传递参数,根据参数列表调用对应的构造方法。
2.5.2 构造方法重载演示
Student
class Student{ private int age; private String name; public Student(){ System.out.println("我是无参数构造方法....."); } public Student(int age,String name){ System.out.println("我是两个参数构造方法......int .... String "); this.age = age; this.name = name; } public Student(String name,int age){ System.out.println("我是两个参数构造方法.....String...int "); this.age = age; this.name = name; } }
StudentTest
public class StudentTest{ public static void main(String[] args){ new Student();//创建对象不传参数,无参数构造方法就会执行 new Student(18,"花花");//创建对象时传递了两个参数,第一个类型int,第二个类型String new Student("小明",60); } }
构造方法总结 1.每个类默认会有一个无参构造,权限修饰符与当前类一致。 2.显示定义了构造器(构造方法)不论是有参还是无参默认无参将会消失,没有无参构造方法将不能通过无参构造方式创建对象。
2.6 构造方法相互调用
2.6.1 构造方法相互调用描述
构造方法支持相互调用,借助this关键字。 格式:this(参数)
2.6.2 构造方法相互调用实现
public Student(){ this(18,"张三"); System.out.println("一个参数构造器......"); } public Student(int age,String name){ this(age,name,"女"); System.out.println("两个参数构造方法....."); } public Student(int age,String name,String gender){ System.out.println("三个参数构造方法....."); }
以上三个构造方法都会执行。
2.6.3 构造方法相互调用注意事项
1.构造方法不能出现循环调用。 2.构造方法不能自己调用自己。 3.每个构造方法中只能出现一次调用其他构造方法。
三 程序初始化过程
3.1 创建一个Student对象
学生类
public class Student{ private int age = 16; private String name = "李四"; public Student(int age,String name){ this.name = name; this.age = age; } }
测试类
public class StudentTest{ public static void main(String[] args){ Student s = new Student(12,"zhangsan"); } }
3.2 对象在JVM中初始化步骤
(1)、测试类中main方法是程序的入口,先加载StudentTest.class字节码加载进方法区中生成一个java.lang.Class (2)、将main方法压栈:在栈内存中开辟一块内存空间为运行main方法服务 (3)、在栈内存中为局部变量s申请一块空间,为s变量赋值会创建Student对象 (4)、先加载Student.class文件加载进内存的方法区中生成一个java.lang.Class对象 (5)、在栈内存为s开辟空间 (6)、在堆内存为学生对象开辟空间 (7)、对学生对象的成员变量进行默认初始化 (8)、对学生对象的成员变量进行显示初始化 (9)、通过构造方法对学生对象的成员变量赋值 (10)、学生对象初始化完毕,把对象地址赋值给s变量
3.3 内存图
四 static关键字
4.1 什么是static
static在权限修饰符的后面出现,表示静态修饰,可以修饰成员变量和成员方法以及内部类
4.2 static演示
4.2.1 static修饰成员变量
修饰成员变量: 权限修饰符 静态关键字 数据类型 变量名 = 变量值;
class Student{ public static int classNo; }
静态成员变量赋值:类名.变量名 = 值
Student.classNo = 1201;
静态成员变量取值:数据类型 变量名 = 类名.变量名
//用一个变量存起来 int classNo = Student.classNo; //直接输出 System.out.println(Student.classNo);
4.2.2 static修饰成员方法
修饰成员方法: 权限修饰符 静态关键字 返回值类型 方法名(参数列表){ 方法体}
class Student{ public static void method(){ System.out.println("我是无参数返回值静态方法,通过类名.方法名就可以调用我啦"); } public static int max(int num1,int num2){ System.out.println("我是有返回值有参数方法,通过类名.方法名调用我时需要传值"); int max = num1 > num2 ? num1 : num2; return max; } }
静态成员方法调用:类名.方法名();
//无参直接调用 Student.method(); //有参有返回值调用 int max = Student.max(10,20); System.out.println(max); //直接输出调用 System.out.println(Student.max(20,30));
4.3 static关键字修饰特点
1、static修饰的成员只会加载一次 2、static修饰的成员在内存中的方法区的静态共享区中 3、static修饰的成员(成员方法和成员变量)可以直接通过类名.调用也可以通过对象名.调用 4、static修饰的成员被类的所有对象共享 5、static修饰的内容随着类的加载而加载
4.4 static内存图
4.5 注意事项
① 静态不能访问非静态
public class Test{ int a = 10; public static void show(){ System.out.println(a);//报错:因为静态不能访问非静态 } }
② 非静态能够访问静态和非静态
public class Test{ int a = 10; static b = 100; public void show(){ System.out.println(a);//非静态方法中访问非静态成员变量 System.out.println(b);//非静态方法中访问静态成员变量 } }
③ 静态中不能有this关键字
public class Test{ int a = 10; public static void show(){ this.a = 18; System.out.println(this); } }
思考:什么情况下使用静态修饰?
面试题: 1.静态成员变量与普通成员变量的区别?
生命周期、内存中的位置、调用方式
2.静态成员方法与普通成员方法的区别?
生命周期、内存中的位置、调用方式
五 代码块
5.1 代码块介绍
{ .. }就叫代码块,java中的代码块分为构造代码块、静态代码块、局部代码块、同步代码块(多线程内容)。
5.2 各类代码块演示
5.2.1 构造代码块
定义在类中方法外{},每次构造方法执行前都会先执行构造代码块,可将多个构造方法中相同的代码抽取封装到构造代码块中,这样多个构造方法中无需重复定义这些代码。
class Student{ { //构造代码块 } public Studnet(){ //构造方法 } }
5.2.2 静态代码块
静态代码块只是在构造代码块前面加上一个static关键字就变成了静态代码块,静态代码块用于类加载时进行初始化,只会执行一次。
public Student{ static{ //静态代码块 } public Student(){ //构造方法 } }
面试题 1.构造代码块和静态代码块有什么区别?
5.2.3 局部代码块
局部代码块可以定义在一个局部范围,限定变量的生命周期,提高jvm内存利用率。
public class Student{ public void print() { { System.out.println("我是局部代码块"); } } }
5.2.4 同步代码块(了解)
为了解决并发操作可能造成的异常,java的多线程支持引入了同步监视器来解决这个问题,使用同步监视器的通用方法就是同步代码块。
synchronized(obj){ // 需要被同步的代码块 }
5.3 代码块面试题
-
类中包含构造代码块、静态代码块、构造方法,创建对象时请问执行顺序是?创建两个对象时,执行结果是?
六 链式编程
6.1 链式编程
6.1.1 链表编程介绍
简化代码编写,通过 “.” 连接不同的函数调用。 链式编程前提:
方法的返回值类型必须为引用类型。如果返回对象中有可调用的方法,可以通过链式连续调用。
6.1.2 链式编演示
public class Demo01{ public Demo02 getDemoo2(){ return new Demo02(); } } class Demo02{ public Demo03 getDemo03(){ return new Demo03(); } } class Demo03{ public String getStr(){ return "java编程!"; } public void println(){ System.out.println("java!"); } }
传统方式调用
Demo01 d1 = new Demo01(); Demo02 d2 = d1.getDemo02(); Demo03 d3 = d2.getDem03(); String str = d3.getStr(); d3.println();
链式调用
String str = new Demo01().getDemo02().getDemo03().getStr(); new Demo01().getDemo02().getDemo03().getStr().toString(); new Demo01().getDemo02().getDemo03().println();
七、package关键字
7.1 package关键字介绍
package理解为包,包相当于windows系统里面的文件夹。 作用:
用来解决同一个路径下不能存在同名文件的问题(分类管理)。
包划分方式:
按照功能划分。 按照模块划分。
定义包的格式
package 包名。 多级包用.分开即可。
定义包的注意事项
package语句必须是程序的第一条可执行的代码。 package语句在一个java文件中只能有一个。 如果没有package,默认表示无包名。
7.2 带包的类编译和运行
手动式
javac编译当前类文件。 手动建立包对应的文件夹。 把a步骤的class文件放到新建的最终文件夹下。 通过java命令执行。注意了:需要带包名称的执行。 java com.java.HelloWorld。
自动式
javac编译的时候带上-d即可。 javac -d . HelloWorld.java。 通过java命令执行需要带上包名称执行。
案例
package com.java.demo01; class HelloWorld{ public static void main(String[] args){ System.out.println("HelloWorld!"); } }
八 不同包下类之间的访问
8.1 带包名访问
定义类
功能类com.java.demo包下。 Calculate类,有个sum()方法求两个数相加相加。 测试类com.java.test包下。 CalculateTest类main方法中调用Caculate的sum方法。
访问
com.java.demo.Calculate calculate = new com.java.demo01.Caluclate(); calculate.sum(28,80);
8.2 import关键字
8.2.1 import关键字介绍
用于解决不同包之间类相互访问,A类访问B类的方法,需要加上A类的包类路径。这种方式比较麻烦,java提供了导包功能。
导报格式:
import 包名;
注意事项:
这种方式导入是到类的名称。 虽然可以最后写*,但是不建议。
面试题:
package,import,class有没有顺序关系?