一、成员变量 VS 局部变量
1、定义的位置不同
成员变量定义在方法体之外,局部变量定义在类体中或者是方法的形式参数
2、内存位置不同
成员变量的值存储在堆上,局部变量的值存储在栈上
3、声明周期不同
成员变量的存储空间随着对象的销毁和销毁(释放),局部变量岁方法栈帧的销毁而销毁
4、初始值不同
局部变量没有被自动赋予默认初值,而成员变量会有默认初值
二、方法引用类型的形式参数
1、实参和形参的值传递方式是复制传递(将实参的值复制一份,赋值给形参)
2、引用类型的变量,在调用方法,和被调用方法中,都属于各自方法中定义的局部变量
3、引用类型的实参和形参的值,在调用方法和被调用方法中各自都有一份,但是,引用类型的实参和形参所指向的数据,是同一份数据
/**
* 方法引用类型的形式参数
*
*/
class Demo2{
int a;
}
public class Demo1 {
public static void main(String[] args) {
Demo2 d1 = new Demo2();
d1.a = 1;
Demo2 d2 = new Demo2();
d2.a = 2;
System.out.println(d1.a);
System.out.println(d2.a);
function1(d1, d2);
System.out.println(d1.a);
System.out.println(d2.a);
System.out.println("******************华丽的分割线*************************");
System.out.println(d1.a);
System.out.println(d2.a);
function2(d1, d2);
System.out.println(d1.a);
System.out.println(d2.a);
}
//方法的参数都是引用类型
public static void function1(Demo2 d1, Demo2 d2){
//
Demo2 temp;
temp = d1;
d1 = d2;
d2 = temp;
System.out.println("function1:d1.a = " + d1.a + ",d2.a = " + d2.a);
//当方法被调用执行完后,形式参数随着方法栈帧的销毁而销毁,因此对象的值并没有被交换
}
public static void function2(Demo2 d1, Demo2 d2){
//交换d1 和 d2 这两个引用变量所指向的对象的 成员变量a 的值
int temp; //局部变量
temp = d1.a;
d1.a = d2.a;
d2.a = temp;
System.out.println("function2:d1.a = " + d1.a + ",d2.a = " + d2.a);
}
}
三、构造方法
1、作用——在创建对象的时候,完成对象成员变量的初始化工作(在创建对象的最后一步执行构造方法,对成员变量完成初始化)
2、语法:
(1)、方法名固定,必须和类名相同
(2)、方法声明中,没有返回值类型这一项
(3)、其他和普通的方法定义类似
3、注意事项:
(1)、构造方法可以重载
a、重载条件和普通方法重载条件相同
b、可以根据new类名(实参列表)中的实参列表指明创建某对象时所使用的构造方法
(2)、如果没有定义任何构造函数,则JVM会自动帮我们添加一个默认构造函数,否则不会
(3)、构造方法的执行时机:创建对象的最后一步,JVM用来初始化对象中成员变量的值
package com.cskaoyan.Demo;
public class constructorDemo{
public static void main(String [] args) {
ConstructorClass constructor1 = new ConstructorClass();
ConstructorClass constructor2 = new ConstructorClass("zhangsan");
}
}
class ConstructorClass{
// 成员变量
String name;
int age;
boolean isMale;
int sno;
//无参构造函数
public ConstructorClass(){
System.out.println("无参构造方法:");
System.out.println("name——" + name + ", age——" + age + ", isMale——" + isMale + ", sno——" + sno);
}
// 一参数构造方法
public ConstructorClass(String nameValue){
name = nameValue;
System.out.println("一参构造方法");
System.out.println("name——" + name + ", age——" + age + ", isMale——" + isMale + ", sno——" + sno);
}
// 四参构造方法
public ConstructorClass(String nameValue, int ageValue, boolean isMaleValue, int snoValue){
name = nameValue;
age = ageValue;
isMale = isMaleValue;
sno = snoValue;
System.out.println("四参构造方法");
System.out.println("name——" + name + ", age——" + age + ", isMale——" + isMale + ", sno——" + sno);
}
}
四、this关键字
1、表示当前引用对象
2、如何确定this指的是哪个对象?
(1)、如果this出现在构造方法中,指的是正在创建的那个对象
(2)、如果this出现在成员方法中,因为成员方法总是以对象名.的方式访问,使用对象访问该方法,this就指的是哪个对象
3、this的作用
(1)、解决成员变量的隐藏问题
(2)、访问对象的成员变量和成员方法
(3)、访问对象的构造方法
4、成员变量的隐藏问题
(1)、方法中定义了和类中成员变量同名的局部变量
(2)、在方法体中,通过同名变量的变量名来访问变量值,我们只能访问到方法体中的那个局部同名变量的值,而访问不到同名成员变量的值
(3)、在方法体中,就好像同名成员变量被同名局部变量给隐藏起来了
解决方法:
成员变量的隐藏,问题的解决?——可以通过给成员变量的变量名前加一个用来区分成员变量的前缀——this
package com.cskaoyan.Demo;
public class thisDemo {
public static void main(String[] args) {
String name = "Lisa";
Student s1 = new Student(name);
System.out.println(s1.name);
Student s2 = new Student("Jennie");
System.out.println("name——" + s2.name + ", age——" + s2.age + ", isMale——" + s2.isMale + ", sno——" + s2.sno);
Student s3 = new Student("Jennie", 25);
System.out.println("name——" + s3.name + ", age——" + s3.age + ", isMale——" + s3.isMale + ", sno——" + s3.sno);
}
}
class Student{
// 成员变量
String name;
int age;
boolean isMale;
int sno;
// 定义无参构造方法
public Student(){
// this调用构造方法,必须处在构造方法的第一条语句的位置
this("未知", -1, true, -1);
}
// 一参构造方法
public Student(String name){
this.name = name;
}
// 2参构造方法
public Student(String name, int age){
this.name = name;
this.age = age;
}
//四参构造方法
public Student(String name, int age, boolean isMale, int sno){
this.name = name;
this.age = age;
this.isMale = isMale;
this.sno = sno;
}
}
五、static关键字
1、static关键字:可以修饰成员变量和成员方法
被static修饰的成员变量、成员方法,其是按照严格的面向对象思想,他们已经不是严格意义上的成员(成员变量、成员方法)。但习惯上,我们成static修饰的成员变量为静态成员变量(简称静态变量),称被static修饰的成员方法为静态成员方法(简称静态方法)
2、特点:
(1)、被该类的所有对象所共享(判定是否使用static关键字)
a、当static修饰了成员变量,该成员变量的值就不再存储在对象中了,而是单独存储了一份,被类的所有对象所共享
b、当static修饰成员方法,该方法被当前类的所有对象共享
当前类对象.方法(和普通成员方法从共享的角度,几乎没有太大区别)
(2)、可以直接通过类名访问static修饰的成员变量和成员方法
(3)随着类的加载而加载:
a、static 修饰的是成员变量,类加载时分配存储空间,并赋予默认初值
b、static修饰成员方法,类加载完毕,就可以通过类名访问
(4)、优先于对象而存在(不依赖于对象而存在)
3、注意事项:
(1)、静态方法中不能访问非静态成员变量和非静态成员方法(反之可以)
a、无法访问,当前对象的非静态成员变量 或 当前对象的非静态成员方法
b、但是,在静态方法中,可以访我们子集new出来的对象的非静态成员变量或非静态成员方法
(2)、静态方法中不能使用this
(3)、不管 静态方法还是非静态方法中,都不能使用static关键字
4、被static修饰的成员变量的存储位置——方法区中
5、静态成员 VS 普通成员变量
(1)、所属不同
a、静态变量属于类,所有也称类变量
b、成员变量属于对象,所有也称为实例变量(对象变量)
(2)、内存中的位置不同
a、静态变量存储在方法区中
b、成员变量存储在堆内存中
(3)、内存中出现的时间不同
a、静态变量随着类的加载而加载,随着类的消失而消失(先出现在内存中)
b、成员变量随着对象的创建为存在,随着对象的消失而消失(后出现在内存中)
(4)、访问方式不同
a、静态变量可以通过类名调用,也可以通过对象调用
b、成员变量只能通过对象名调用
package com.cskaoyan.Demo;
public class staticDemo {
public static void main(String[] args) {
// 随着类加载而加载,可以通过类名. 访问静态成员变量、静态成员方法
System.out.println(StudentInfo.IntStatic);
System.out.println("********华丽的分割线**********");
StudentInfo s1 = new StudentInfo();
StudentInfo s2 = new StudentInfo();
// 被该类的所有对象所共享,可以通过对象名. 访问
System.out.println(s1.IntStatic);
System.out.println(s2.IntStatic);
System.out.println("********华丽的分割线**********");
// 直接通过类名访问static修饰的成员变量和成员方法
System.out.println(StudentInfo.IntStatic);
StudentInfo.methodStatic();
}
}
class StudentInfo{
// 定义成员变量
String name;
int age;
boolean isMale;
int sno;
// 定义静态成员变量
static int IntStatic;
// 定义静态成员方法
public static void methodStatic(){
System.out.println("静态成员函数被调用");
}
// 无参构造方法
public StudentInfo(){}
//四参构造方法
public StudentInfo(String name, int age, boolean isMale, int sno){
this.name = name;
this.age = age;
this.isMale = isMale;
this.sno = sno;
}
}
六、代码块
1、定义:在Java中,使用{}括起来的代码被称为代码块
2、局部代码块——在方法体中,通常开发中没人用
优点:限定变量生命周期,及早释放,提高内存利用率(这个优点理论上确实存在,但这个优点在现在JVM中的效果微乎其微,甚至可以忽略不计)
我们在开发中,同时还要追求,代码可维护性(包括代码的可读性)
3、构造代码块
(1)、定义位置——定义在方法体之外
(2)、执行时机——每次创建对象的时候,而且先于构造方法执行
(3)、注意事项——如果多个构造代码块,则这多个构造代码块,按照书写的先后顺序执行
4、静态代码块
(1)、定义位置:类中方法体之外,但同时代码块被static关键字修饰
(2)、执行时机:随类加载而执行
(3)、注意事项:
a、静态代码块,属于静态上下文,在静态代码块中,不能非静态的成员变量和成员方法
b、因为随着类加载而加载,所以在同一个JVM中,只会执行一次
5、同步代码块(多线程的时候学习)
七、package关键字
1、作用:
(1)、类比操作系统中用来组织文件的文件夹,Java语言中,用包来组织类
(2)、包还可以用来解决 类同名的问题 ,不同包下可以存放不同名的类
(3)、Java语言中通过全类名唯一确定一个类,全类名 = 包名 + 类名
2、语法
package关键在后跟包名,且这条语句必须放在Java文件第一条语句的位置
3、包的命名方式 —— 域名反转的方式
4、注意事项:
当一个Java文件中,没有package关键字定义类所做包时,类所属的包为默认包
八、import关键字
1、作用:
(1)、当类体中的使用了与当前类不同包的类名是,编译器编译时因为无法找到该类的定义而失败
(2)、使用import 声明,为编译器题干该类的定义信息
2、语法:
(1)、import语句后根类的全限定名
(2)、类的全限定名是指包名+类名,在Java语言中,包名+类名才能唯一确定一个类
3、注意事项:
(1)、import声明一般紧跟在package声明之后,必须在类声明之前
(2)、Java语言核心包java.lang包中的类将被隐式导入,可以直接使用其中的类
(3)、可以使用import <包名>.*;一次导入一个包下的多个类 ,但是这种方式不会自动嵌套导入子包中的类