Javabean的特点

  • 私人成员变量
  • 公共的成员方法
  • 利用get/set成员方法对私人变量进行取值/赋值

构造方法(构造器)

构造方法(也叫构造器)是一种特殊的方法,定义的位置是在类中,成员方法外,和成员变量,成员方法是平级关系,定义构造方法和定义一般的成员方法很像,它的特点是与类同名,但是没有返回值,其语法格式如下:

[修饰符] 构造方法名(形参列表){
        //零到多条可执行语句组成构造方法的执行体
    } 
    例如:
    自定义学生类,其中有一个空参的构造方法
    class Student{
        public Student(){
            System.out.println("这是学生类的空参构造方法");
        }
    }
构造方法的重载
class Person{
        private int id;
        public Person(){}           //空参构造方法
        public Person(int a){   //重载构造方法,有一个int型参数
            id = a; //在构造方法中对实例变量赋值
            System.out.println("这是带有一个参数的构造方法");
        }
        public Person(int a,int b){
            System.out.println("这是带有两个参数的构造方法");
        }
    }
构造方法需要注意的事项
  • 方法名与类名相同
  • 没有返回值 也不能使用void

默认的构造方法

定义一个类时,如果没有显示的定义构造方法,这时系统会默认给这个类加上一个无参的构造方法,并且构造方法里面没有任何语句。但一旦定义了构造方法,系统将不会默认再给类添加任何构造方法。

构造方法的使用

在程序中使用new关键字创建一个类的实例化对象的时候,就是去调用该类的相应的构造方法,此时应注意,根据构造方法的形参列表的不同来调用不同的构造方法,调用不存在的构造方法肯定编译报错

class TestDemo{
        //Demo d = new Demo(); //error,没有这样的构造方法
        Demo d = new Demo(10); //调用的是自定义的,有一个参数的构造方法
    }

标准的Javabean练习

定义一个员工类,自己分析出几个成员,然后给出成员变量,构造方法,getXxx()/setXxx()方法,以及一个显示所有成员信息的方法。并测试。

public class Employee {
        private String name;
        private int age;
        private String employeeId;
        //构造空参
        public Employee(){
            System.out.println("this is a constructor");
        }
        //通过set/get方法获取成员变量并赋值
        public void setName(String name){
            this.name= name;
        }
        public String getName(){
            return name;
        }
        public void setAge(int age){
            this.age=age;
        }
        public int getAge(){
            return age;
        }
        public void setEmployeeId(String employeeId){
            this.employeeId=employeeId;
        }
        public String getEmployeeId(){
            return employeeId;
        }
        //构造实参 
        public Employee(String name,int age,String employeeId){
            this.name=name;
            this.age=age;
            this.employeeId=employeeId;
        }
        //定义展示方法
        public void show(){
            System.out.println(name +" "+age +" " + employeeId);
        }
    }
    测试类
    public class EmploeeTest {
        public static void main(String[] args) {
            Employee emp1 = new Employee();//调用空参对象
            Employee emp = new Employee("Tom",24,"25663");//调用实参对象,传参
            emp.show();     //打印结果
        }
    }

this关键字

  • 在构造方法中引用该构造方法正在初始化的对象
  • 在方法中引用正在调用该方法的对象

this关键字是用来指代当前对象的,而从上面的例子可以看到,在构造方法中可以使用this关键字,说明:构造方法被调用的时候,其实对象在堆内存中已经被创建出来了,而构造方法的主要功能就是对实例对象的变量进行初始化的。

static关键字

  • static的真正作用就是用于区分成员变量,方法,内部类,初始化块这四种成员是属于类本身还是属于这个类的实例。
  • 在类定义中,static相当于一个标志,有static修饰的成员属于类本身,没有static修饰的成员属于该类的实例对象。
  • 为了区分这两种不同的成员变量,凡是有static修饰的成员变量/成员方法,称为类变量/类方法,没有static修饰的成员变量/成员方法称为实例变量/实例方法(构造方法不属于实例方法)
static修饰类的成员变量和成员方法(即:类变量,类方法)
静态成员变量(类变量)属于类,可用类名或对象名两种方式进行访问
    静态成员方法(类方法)属于类,可用类名或对象名两种方式进行访问

    只要类存在,程序中就可以访问到类变量,类变量访问的语法
    类名.类变量 Student.name
    只要实例存在,程序中就可以访问到该实例的实例变量,访问实例变量的语法
    实例名.实例变量 s.id
    当然,类变量也可以通过该类的实例来访问,通过实例访问类变量的语法
    实例名.类变量 Student.name/s.name
被static关键字修饰的部分,有如下特点
  • 随着类的加载而加载
  • 优先于对象存在(因为类的加载优先于对象的创建)
  • 被类的所有实例对象共享(存在于方法区中的静态区,如果是一个类变量的话,任何一个对象对该变量进行修改,都会在其他对象中得到体现),这也是我们在定义一个类时,判断是否使用静态关键字的标准
  • 可以通过类名访问(类名.静态变量名/类名.静态方法名),也可以使用对象名来访问,推荐使用类名调用,因为静态变量/方法是属于类的

什么时候使用static关键字?使用static关键字的标准

当一个变量或者方法属于一个类,而不是属于这个类的实例对象时,就可以使用static来修饰,这样就可以使用类名.成员(变量/方法)的方式访问这个static变量/方法。 所有这个类的实例对象都能看到对静态变量(类变量)的更改

static方法重点注意事项
  • 静态方法(类方法)中不能使用this关键字,this关键字代表的是当前对象的引用,但是static关键字修饰的方法是属于类的,随着类的加载而存在,但当类进行加载时,此时实例对象还没有被创建出来,这时是无法使用this关键字的
  • 静态方法只能访问静态成员变量和静态成员方法

静态变量和实例变量的区别


所属

内存位置

出现时间

调用

静态变量

方法区的静态区

随类加载而加载

类名调用,对象名调用

实例变量

对象

堆内存

随对象创建而存在

对象名调用

实例变量和局部变量的区别


声明位置

内存位置

生命周期

初始值

局部变量      

方法内,形参上

栈内存

随方法调用而存在

必须先定义,赋值再使用

实例变量

类内,方法外

堆内存

随对象创建而存在

有默认初始值

main方法是静态的

public static void main(String[] args) {}
  public 被jvm调用,访问权限足够大。
  static 被jvm调用,不用创建对象,直接类名访问
  void被jvm调用,不需要给jvm返回值
  main 一个通用的名称,虽然不是关键字,但是被jvm识别
  String[] args 以前用于接收键盘录入的

练习案例

猜数字小游戏(数据在1-100之间)
分析:
    A:程序产生一个随机数。(被猜的)
    B:键盘录入数据。(你猜的)
    C:把你猜的和被猜的进行比较
        a:大了
        b:小了
        c:猜中了
    D:给出多次猜的机会,猜中就结束。

    import java.util.Scanner;
    public class RandoTest {
        public static void main(String[] args) {
            Scanner input = new Scanner(System.in);
            int b = (int)(Math.random()*100-1);
            while(true){
                System.out.println("请输入一个数字");
                int a = input.nextInt();
                if(a>b){
                    System.out.println("大了");
                }else if(a<b){
                    System.out.println("小了");
                }else if(a>100&&a<1){
                    System.out.println("输入错误");
                }else{
                    System.out.println("猜对了");
                    break;
                }
            }
        }
    }

代码块

代码块 在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块

  • 局部代码块

在方法中出现,直接用{}括起来的部分,就是局部代码块 作用:限定变量生命周期,及早释放,提高内存利用率

  • 构造代码块(也叫初始化块)

在类中,方法外出现;多个构造方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行,若多个构造代码块,则他们之间是顺序执行 作用:抽取构造方法中相同的部分,提高利用率

  • 静态代码块

在类中,方法外出现,加了static修饰的{},或者可以理解成,加了static修饰的构造代码块 作用:给类进行初始化(类变量的初始化),在加载的时候就执行,并且只执行一次

代码块的作用
  1. 静态代码块是对类进行初始化的(主要是对类变量/静态变量进行初始化)
  2. 构造代码块和构造方法主要是对实例对象进行初始化的
  3. 局部代码块是用来规定变量的作用范围,提高内存使用效率,节省空间的

面试题 看代码说结果

class Code {
        static {
            int a = 1000;
            System.out.println(a);
        }

        //构造代码块
        {
            int x = 100;
            System.out.println(x);
        }

        //构造方法
        public Code(){
            System.out.println("code");
        }

        //构造方法
        public Code(int a){
            System.out.println("code");
        }

        //构造代码块
        {
            int y = 200;
            System.out.println(y);
        }

        //静态代码块
        static {
            int b = 2000;
            System.out.println(b);
        }
    }

    class CodeDemo {
        public static void main(String[] args) {
            //局部代码块
            {
                int x = 10;
                System.out.println(x);
            }
            //找不到符号
            //System.out.println(x);
            {
                int y = 20;
                System.out.println(y);
            }
            System.out.println("---------------");
            Code c = new Code();
            System.out.println("---------------");
            Code c2 = new Code();
            System.out.println("---------------");
            Code c3 = new Code(1);
        }
    }