当我们编写一个类时,其实就是在描述其对象的属性和行为,而并没有产生实质上 的对象,只有通过new关键字才会产生出对象,这时系统才会分配内存空间给对象, 其方法才可以供外部调用。我们有时候希望无论是否产生了对象或无论产生了多少 对象的情况下,某些特定的数据在内存空间里只有一份,例如所有的中国人都有个 国家名称,每一个中国人都共享这个国家名称,不必在每一个中国人的实例对象中 都单独分配一个用于代表国家名称的变量。
如果想让一个类的所有实例共享数据,就用类变量!
类属性、类方法的设计思想
类属性作为该类各个对象之间共享的变量。在设计类时,分析哪 些属性不因对象的不同而改变,将这些属性设置为类属性。相应 的方法设置为类方法。
如果方法与调用者无关,则这样的方法通常被声明为类方法,由 于不需要创建对象就可以调用类方法,从而简化了方法的调用。
使用范围:
在Java类中,可用static修饰属性、方法、代码块、内部类
被修饰后的成员具备以下特点:
随着类的加载而加载
优先于对象存在
修饰的成员,被所有对象所共享
访问权限允许时,可不创建对象,直接被类调用
代码块代码块(或初始化块)的作用:
对Java类或对象进行初始化
代码块(或初始化块)的分类:
一个类中代码块若有修饰符,则只能被static修饰,称为静态代码块 (static block),没有使用static修饰的,为非静态代码块。
static代码块通常用于初始化static的属性
class Person {
public static int total;
static {
total = 100;//为total赋初值
}
…… //其它属性或方法声明
}
静态代码块:用static 修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 不可以对非静态的属性初始化。即:不可以调用非静态的属性和方法。
4. 若有多个静态的代码块,那么按照从上到下的顺序依次执行。
5. 静态代码块的执行要先于非静态代码块。
6. 静态代码块随着类的加载而加载,且只执行一次。
非静态代码块:没有static修饰的代码块
1. 可以有输出语句。
2. 可以对类的属性、类的声明进行初始化操作。
3. 除了调用非静态的结构外,还可以调用静态的变量或方法。
4. 若有多个非静态的代码块,那么按照从上到下的顺序依次执行。
5. 每次创建对象的时候,都会执行一次。且先于构造器执行。
class Person {
public static int total;
static {
total = 100;
System.out.println("in static block!");
}
}
public class PersonTest {
public static void main(String[] args) {
System.out.println("total = " + Person.total);
System.out.println("total = " + Person.total);
}
}
程序中成员变量赋值的执行顺序
声明成员变量的默认初始化
显式初始化、多个初始化块依次被执行(同级别下按先后顺序执行)
构造器再对成员进行初始化操作
通过”对象.属性”或”对象.方法”的方式,可多次给属性赋值
final在Java中声明类、变量和方法时,可使用关键字final来修饰,表示“最终的”。
final标记的类不能被继承。提高安全性,提高程序的可读性。
String类、System类、StringBuffer类
final标记的方法不能被子类重写。
比如:Object类中的getClass()。
final标记的变量(成员变量或局部变量)即称为常量。名称大写,且只 能被赋值一次。
final标记的成员变量必须在声明时或在每个构造器中或代码块中显式赋 值,然后才能使用。
final double MY_PI = 3.14
final修饰类
final class A{
}
class B extends A{ //错误,不能被继承。
}
中国古代,什么人不能有后代,就可以被final声明,称为“太监类”!
final修饰方法
class A {
public final void print() {
System.out.println("A");
}
}
class B extends A {
public void print() { // 错误,不能被重写。
System.out.println(" xxx");
}
}
final修饰变量——常量
class A {
private final String INFO = "The sun brand"; //声明常量
public void print() {
}
}
常量名要大写,内容不可修改。
static final:全局常量
//这是一个全局常量
public static final String COMPANY = "The sun brand";
final 表示最终的,完美的 可以修饰类,方法,变量 final修饰类,表明这个类时终极类,不可以被子类扩展 ,final类一定重写了toString,hashCode equals final修饰方法,表明这个方法是终极方法,不可以被子类重写 final修饰量,表明这个量是一个最终量,它的特点是只能必须赋值一次,不赋值不行。 public static final修饰量称为全局常量
package com.day13.Statict;
import com.sun.jmx.snmp.SnmpUnknownAccContrModelException;
public class Employee {
//共享数据,被修饰的成员称为静态成员,或类成员
//静态属性或类变量,和对象无关
//类属性可以隐性的初始化
//这是一个全局常量
public static final String COMPANY;//public static String company;
static {
COMPANY = "The sun brand";
}
//静态方法或类方法,和对象无关
public static void test() {
System.out.println("company:" + COMPANY);//静态成员之间可以互访
}
private static int no = 1; //声明(永远最先执行),显式赋值
private static Employee e ;
public static void test2() {
e = new Employee();
e.name = "某员工";//可以通过创建的对象来间接访问对象属性
e.age = 19;
e.salary = 9999;
System.out.println(e);
}
//静态语句块,静态代码块可以有多个,按照赋值顺序执行 类初始化器
static {
System.out.println("Employee static1{}.....");//类加载时执行一次,仅执行一次,
no = 100;
}
static {
System.out.println("Employee static2{}.....");//类加载时执行一次,仅执行一次,
no = 1000;
}
private String name;
private int age;
private double salary;
// 空final非常危险, 必须尽快完成一次赋值, 在构造器中为其完成一次赋值, 在所有构造器中都必须赋值.
private final int id;//员工号,自动生成
public Employee() {
}
public Employee(String name, int age, double salary) {
// this.id = no++;//每个对象的id 都可以被不同的no赋值,可以自动生成
this.name = name;
this.age = age;
this.salary = salary;
}
{//非静态语句块 随着对象创建 执行仅有的一次 并且先于构造器执行,无论时哪个构造器,都不影响其执行
System.out.println("Employee{}....");
this.id = no++;
}
public int getId() {
return id;
}
// public void setId(int id) {
// this.id = id;
// }
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public double getSalary() {
return salary;
}
public void setSalary(double salary) {
this.salary = salary;
}
@Override
public String toString() {
return "Employee{" +
"name='" + name + ''' +
", age=" + age +
", salary=" + salary +
", id=" + id +
'}';
}
}



