构造函数:
构造函数的作用:给对应的对象进行初始化。
构造函数定义的格式:
修饰符 函数名(形式参数){
函数体...
}
构造函数要注意的细节:
- 构造函数是没有返回值类型的
- 构造函数的函数名必须与类名一致
- 构造函数并不是我们手动调用的,而是在创建对应的对象时,jvm就会主动调用到对应的构造函数
- 如果一个类没有显式的写上一个构造方法时,那么Java编译器会为该类添加一个无参的构造函数的。
- 如果一个类已经显式写上一个构造方法时,那么java编译器则不会再为该类添加一个无参的构造方法。
- 构造函数时可以在一个类中以函数重载的形式存在多个的
java编译器为我们添加的构造方法的权限修饰符与类的权限修饰符一致/
jdk提供了一个开发工具(javap.exe)给我们进行反编译。
javap反编译工具的使用格式:
javap -c(反编译代码) -l(打印行号和本地变量表) -private (显示类和所有成员) 类名
构造函数与普通函数的区别:
- 构造函数时没有返回值类型的
- 普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void
- 构造函数的函数名必须要与类名一致
- 普通函数的函数名只要符合标识符的命名规则即可
- 构造函数是在创建的时候由jvm调用的
- 普通函数是由我们使用对象调用的,一个对象可以调用多次普通的函数
- 构造函数的作用用于初始化一个对象
- 普通函数是用于描述一类事物的公共行为的
构造代码块:给对象进行统一的初始化。
构造代码块的格式:
{
构造代码块;
}
注意:构造代码块的大括号必须位于成员位置上。
代码块的类别:
- 构造代码块
- 局部代码块 大括号位于方法之内 作用:缩短局部变量的生命周期,节省一点点内存
- 静态代码块
构造代码块要注意的事项:
- java编译器b编译一个java源文件的时候,会把成员变量的声明语句提前至一个类的最前端。 (注意是声明,不是赋值)
- 成员变量的初始化工作其实都是在构造函数中执行的。
- 一旦经过java编译器b编译后,那么构造代码块d的代码就会被移动到构造函数中执行,是在构造函数前面执行的,构造函数中的代码是最后执行的。
- 成员变量的显式初始化与构造代码块的代码是按照当前代码的顺序执行的。
如果存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量(java采取的是就近原则的机制访问的。)
1 public class Creative { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 Animal a=new Animal(); 6 a.eat(); 7 } 8 9 } 10 class Animal{ 11 String name="狗"; 12 String color; 13 public void eat() { 14 String name="鸡"; 15 System.out.println(name+"在吃."); 16 } 17 }
比如这里就是鸡在吃而不是狗在吃。
ps:栈内存又叫方法栈,一个方法要运行的时候,jvm会在栈内存中开辟一片属于这个方法的空间,让这个方法在这片空间执行
this关键字:this关键字代表了所属函数的调用者对象
this关键字的作用:
- 如果存在同名的成员变量与局部变量时,在方法内部默认是访问局部变量的数据,可以通过this关键字指定访问成员变量的数据。
- 在一个构造函数中,可以调用另外一个函数初始化对象。 this(形式参数1,形式参数2...),调用本类的对应数量参数的构造方法
this关键字要注意的事项:
- 如果存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量(java采取的是”就近原则“的机制访问的。)
- 如果在一个方法中访问了一个变量,该变量只存在成员变量的情况下,那么java编译器会在该变量的前面添加this关键字。
一个函数的形式参数也是属于局部变量
public Student(String name,int id) { name=name; //这里的两个name都是局部变量的name,也就是形式参数的name,而不会对成员变量的name造成改变,相当于局部变量自己给自己赋值 id=id; //同理 }
正确的应该是这样:
public Student(String name,int id) { this.name=name; //局部变量的name给成员变量赋值 this.id=id; }
this的第二个作用:比如说,在两个参数的构造方法中调用一个参数的构造方法
class Student{ String name; int id; public Student(String name,int id) { this(name); //调用本类中一个参数的构造方法 //this.name=name; //局部变量的name给成员变量赋值 //this(); //无参的构造方法被调用 this.id=id; System.out.println("两个参数的构造方法被调用了"); } public Student(String name) { this.name=name; System.out.println("一个参数的构造方法被调用"); } public Student() { System.out.println("无参构造方法被调用"); } } public static void main(String[] args) { // TODO Auto-generated method stub Student s=new Student("狗娃",110); System.out.println("姓名: "+s.name+"身份证: "+s.id); }
this关键字调用其他构造函数要注意的事项:
- this关键字调用其他的构造函数时,this关键字必须要位于构造函数中的第一个语句
- this关键字在构造函数中不能出现相互调用的情况,因为是一个死循环
方法区(数据共享区):数据共享
static修饰的成员变量(静态成员变量) 只会在数据共享区中维护一份,而非静态成员变量的数据会在每个对象中都维护一份的。 但是某个修改这个静态变量,就会影响所有的对象的属性
static (静态\修饰符)
- static修饰成员变量 : 如果有数据需要被共享给所有对象使用时,那么就可以使用static修饰
- static修饰成员函数
静态成员变量的访问方式:
- 可以使用对象进行访问 格式:对象.变量名
- 可以使用类名进行访问 格式:类名.变量名
注意:
- 非静态的成员变量只能使用对象进行访问,不能使用对象进行访问。
- 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候才使用static修饰
static修饰成员变量的应用场景: 如果一个数据需要被所有对象共享使用的时候,这时候即可使用static修饰
class Emp{ static int count=0; { count++; } public Emp() { } public void showCount() { System.out.println("创建了"+count+"个对象"); } } public class Count { public static void main(String[] args) { // TODO Auto-generated method stub Emp e1=new Emp(); new Emp(); new Emp(); new Emp(); new Emp(); e1.showCount(); } }