作者:~小明学编程
文章专栏:JavaSE基础
格言:目之所及皆为回忆,心之所想皆为过往
目录
对象的构造及初始化
初始化对象
前面我们通过学习知道了Java李里面的变量必须给它赋上一个初始值才行,否则的话就会报错。
如果是对象的话
class Student {
public int age;
public String name;
public void test() {
System.out.println("姓名:"+name+" 年龄:"+age);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
Student student = new Student();
student.test();
student.age = 18;
student.name = "张三";
student.test();
}
}
这里我们可以看到我们必须通过引用对象才能给其成员赋值,然后才能调用方法实现我们的需求,这样无疑会很麻烦,我们可以通过我们的构造方法解决上述的问题。
构造方法
概念
构造方法(也称为构造器)是一个特殊的成员方法,名字必须与类名相同,在创建对象时,由编译器自动调用,并且在整个对象的生命周期内只调用一次。
class Student {
public int age;
public String name;
public Student (int age,String name){
this.age = age;
this.name = name;
System.out.println("Student方法已被调用");
}
public void test() {
System.out.println("姓名:"+name+" 年龄:"+age);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
Student student = new Student(18,"张三");
student.test();
// student.age = 18;
// student.name = "张三";
// student.test();
}
}
我们可以看到我们在new Student的时候就调用了我们的构造方法,那么之前我们没有写构造方法的时候又是怎么调用构造方法的呢?
这里是因为当我们没有写构造方法的时候会自动生成一个没有参数的构造方法当我们写了构造方法的时候就会调用我们当前的构造方法。
注意:构造方法的作用就是对对象中的成员进行初始化,并不负责给对象开辟空间
特性
1. 名字必须与类名相同
2. 没有返回值类型,设置为void也不行
3. 创建对象时由编译器自动调用,并且在对象的生命周期内只调用一次(相当于人的出生,每个人只能出生一次)
4. 构造方法可以重载(用户根据自己的需求提供不同参数的构造方法)5.构造方法可以有参数也可以没有。
class Student {
public int age;
public String name;
public Student (int age,String name){
this.age = age;
this.name = name;
System.out.println("Student方法已被调用");
}
public Student (int age){
this.age = age;
System.out.println("Student方法已被调用");
}
public void test() {
System.out.println("姓名:"+name+" 年龄:"+age);
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
Student student = new Student(18,"张三");
student.test();
Student student1 = new Student(20);
student1.test();
// student.age = 18;
// student.name = "张三";
// student.test();
}
}
这就是构造方法的重载。
this引用
什么是this引用
this引用指向当前对象(成员方法运行时调用该成员方法的对象),在成员方法中所有成员变量的操作,都是通过该引用去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成
public class Date {
public int year;
public int month;
public int day;
public void setDay(int year, int month, int day){
this.year = year;
this.month = month;
this.day = day;
}
public void printDate(){
System.out.println(this.year + "/" + this.month + "/" + this.day);
}
}
这种用法我们前面已经说过了,this指向当前对象的变量,这样可以排除局部变量对我们方法的影响。
this调用其它方法的使用
public void fun1() {
System.out.println("hello");
}
public void fun2() {
this.fun1();
System.out.println("hi");
}
我们可以通过关键字this来调用当前对象中的其它方法,注意我们不能在静态方法中通过this来调用其它的方法,但是我们可以在普通方法中通过this来调用静态的方法。
this在构造函数中的使用
class Student {
public int age;
public String name;
public Student() {
this("张三");
System.out.println("Student无参数方法");
}
public Student (int age,String name){
this.age = age;
this.name = name;
System.out.println("Student2方法已被调用");
}
public Student (String name){
this.name = name;
System.out.println("Student1方法已被调用");
}
public void test() {
System.out.println("姓名:"+name+" 年龄:"+age);
}
public void fun1() {
System.out.println("hello");
}
public void fun2() {
this.fun1();
System.out.println("hi");
this.fun3();
}
public static void fun3() {
System.out.println("ok");
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
Student student = new Student();
// student.fun2();
}
}
这里我们可以看到我们在this里面加了参数就能够调用其它的构造方法了。但是这里我们要注意的一点是:在构造方法中使用this(),this()必须放在构造方法中的第一行,同时也就是说构造方法中我们只能够使用一个this语句,并且this()这种用法也只能在构造方法中使用。
代码块
代码块概念以及分类
使用 {} 定义的一段代码称为代码块。根据代码块定义的位置以及关键字,又可分为以下四种:
1.普通代码块
2.构造块
3.静态块
4.同步代码块
普通代码块
public static void main(String[] args) {
{ //直接使用{}定义,普通方法块
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
普通代码块就是定义在我们方法中的代码块。
构造代码块
构造块:定义在类中的代码块(不加修饰符)。也叫:实例代码块。构造代码块一般用于初始化实例成员变量。
public class Student{
//实例成员变量
private String name;
private String gender;
private int age;
private double score;
public Student() {
System.out.println("I am Student init()!");
} //实例代码块
{
this.name = "bit";
this.age = 12;
this.sex = "man";
System.out.println("I am instance init()!");
}
public void show(){
System.out.println("name: "+name+" age: "+age+" sex: "+sex);
}
}
public class Main {
public static void main(String[] args) {
Student stu = new Student();
stu.show();
}
}
静态代码块
使用static定义的代码块称为静态代码块。一般用于初始化静态成员变量
class Student {
public int age;
public static int score;
public String name;
{
System.out.println("aaa");
}
static {
score = 10;
System.out.println("ccc");
}
public Student() {
this("张三");
System.out.println("Student无参数方法");
}
public Student (int age,String name){
this.age = age;
this.name = name;
System.out.println("Student2方法已被调用");
}
public Student (String name){
this.name = name;
System.out.println("Student1方法已被调用");
}
public void test() {
System.out.println("姓名:"+name+" 年龄:"+age);
}
public void fun1() {
System.out.println("hello");
}
public void fun2() {
this.fun1();
System.out.println("hi");
this.fun3();
}
public static void fun3() {
System.out.println("ok");
}
@Override
public String toString() {
return "Student{" +
"age=" + age +
", name='" + name + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
Student student = new Student();
System.out.println("---------------------------");
Student student1 = new Student();
}
}
我们可以看到即使我们的静态代码块放在实例代码块的前面但是依然是先执行我们的静态代码块的,并且静态代码块只执行一次。
赋值优先问题
class Student {
public int age;
public String name;
{
System.out.println("aaa");
}
static {
score = 10;
System.out.println("ccc");
}
public static int score=1;
}
public class Dome {
public static void main(String[] args) {
System.out.println(Student.score);
}
}
我们可以看到我们的 public static int score=1;放在在后面此时score的值就是1了,但是放在后面我们不给它初始话的话那么score的值就还是10.
注意事项
注意事项
静态代码块不管生成多少个对象,其只会执行一次
静态成员变量是类的属性,因此是在JVM加载类时开辟空间并初始化的
如果一个类中包含多个静态代码块,在编译代码时,编译器会按照定义的先后次序依次执行(合并)
实例代码块只有在创建对象时才会执行
匿名对象
class Person {
private int age;
private String name1;
public int a;
public void fun() {
System.out.println("hello "+name1);
}
public void setMyName(String myName) {
name1 = myName;
}
public String getMyName() {
return name1;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"age=" + age +
", name='" + name1 + '\'' +
'}';
}
}
public class Dome {
public static void main(String[] args) {
new Person().fun();
System.out.println(new Person().a);
}
}
匿名对象在我们这里只能使用一次如上述,我们在使用的时候不用创建新的引用就是使用该类的方法或者变量,一般在只使用一次的时候比较方便,如果使用该类的方法或者变量比较多的话,还是建议new一个对象使用起来比较方便。