静态方法的调用方法是类名.静态方法名
,但若是是引用.静态方法名
,也不会报错,若引用为空,引用.静态方法名
也不会报错
因为静态方法执行的时候和引用无关
public class Test{
public static void main(){
doSome();
Test tt = new Test();
tt.doSome();
tt = null;
tt.doSome();
}
public static doSome(){
System.out.println("静态方法执行");
}
}
修饰属性:不同对象有同样的属性值可用 static
静态变量在类加载的时候初始化,内存在方法区中开辟,访问的时候不需要创建对象,直接使用类名.静态方法名
调用
当所有对象都有这个属性,并且所有属性的值都是一样的,不会因为对象不同而变化,此时建议定义为静态变量,节省空间
public class Test{
public static void main(String[] args){
Chinese c1 = new Chinese(12424,23,"中国");
Chinese c2 = new Chinese(12567,21,"中国");
Chinese c3 = new Chinese(12865,27,"中国");
}
}
class Chinese{
int idcard;
int age;
String country;
public Chinese(){}
public Chinese(idcard,age,country){
this.idcard = idcaard;
this.age = age;
this.country = country;
}
}
以上代码中,三个中国人的身份证和年龄都各不相同,但是国籍是相同的,所以国籍这个属性可以定义为静态变量
public class Test{
public static void main(String[] args){
Chinese c1 = new Chinese(12424,23,Chinese.country);
Chinese c2 = new Chinese(12567,21,Chinese.country);
Chinese c3 = new Chinese(12865,27,Chinese.country);
}
}
class Chinese{
int idcard;
int age;
static String country = "中国";
public Chinese(){}
public Chinese(idcard,age){
this.idcard = idcaard;
this.age = age;
}
}
修饰方法:什么样的方法定义 static
- 静态方法是随着类的加载而加载的,可通过
类名.静态方法
的方式调用 - 静态方法中只可以调用静态方法、静态属性
- 非静态方法中可以调用静态方法属性、非静态方法属性
- 在静态方法内不能使用
this
关键字和super
关键字
public class Test{
String name;
static String a;
public void m(){}
public static void walk(){}
public static void show(){
//不可以调非静态
//m();
//name = "";
//可以调用静态
System.out.println(a); //这里省略的不是this.而是类名.
System.out.println(Test.a);
walk();
}
}
当所有的对象执行这个方法的时候,产生的影响是一样的
那么这个方法就不再属于某一个对象的动作了,可以将这个方法提升为类级别的动作、模板级别的
大多数方法都是实例方法,因为一般都需要对象参与
大多数“工具类”都是静态方法,方便调用,无需创建对象
public class Test{
public static void main(String[] args){
System.out.println(Mathutil.sumInt(10 , 20));
}
}
class Mathutil{
public static int sumInt(int a ,int b){
return a + b;
}
}
静态代码块
语法格式:static{ java语句; }
静态代码块在类加载的时候运行,且只执行一次
静态代码块可以编写多个,遵循自上而下的顺序执行
public class Test{
static{
System.out.println("代码块1");
}
static{
System.out.println("2代码块2");
}
static{
System.out.println("3代码块3");
}
public static void main(String[] args){
System.out.println("主方法执行!");
}
}
执行结果如下:
通常静态代码块用来预备工作:初始化连接池、解析XML配置文件…
实例代码块
语法格式:{ java语句; }
实例代码块在对象初始化的时候运行,且只执行一次
实例代码块可以编写多个,遵循自上而下的顺序执行
public class Test{
public Test(){
System.out.println("构造方法");
}
{
System.out.println("实例代码块1");
}
{
System.out.println("实例代码块2");
}
{
System.out.println("实例代码块3");
}
public static void main(String[] args){
System.out.println("主方法");
Test tt = new Test();
}
}
执行结果如下:
实例代码块在对象初始化的时候运行,每创建一个对象就运行一次
class Untitled {
public static void main(String[] args) {
Untitled t1 = new Untitled();
Untitled t2 = new Untitled();
}
public Untitled(){
System.out.println("构造方法");
}
{
System.out.println("实例代码块1");
}
}
执行结果如下:
练习
判断执行结果
对象创建之前,因为调用了父类的结构,所以会加载父类,所以最先执行的是静态代码块,会在类加载的时候执行
后面的实例代码块则是在执行构造器的时候执行
class Untitled {
public static void main(String[] args) {
new C();
}
}
class A{
static{
System.out.println("A类静态代码块");
}
{
System.out.println("A类实例代码块");
}
public A(){
System.out.println("A类无参构造器");
}
}
class B extends A{
static{
System.out.println("B类静态代码块");
}
{
System.out.println("B类实例代码块");
}
public B(){
System.out.println("B类无参构造器");
}
public B(String bb){
this();
System.out.println("B类有参数构造器"+bb);
}
}
class C extends B{
static{
System.out.println("C类静态代码块");
}
{
System.out.println("C类实例代码块");
}
public C(){
super("草莓");
System.out.println("C类无参构造器");
}
}
执行结果如下
判断执行结果
class Untitled extends A{
static{
System.out.println("4444444444444");
}
{
System.out.println("5555555555555");
}
public Untitled(){
System.out.println("6666666666666");
}
public static void main(String[] args) {
System.out.println("7777777777777");
System.out.println("-------------");
new Untitled();
System.out.println("=============");
new Untitled();
System.out.println("'''''''''''''");
new A();
}
}
class A{
static{
System.out.println("1111111111111");
}
{
System.out.println("2222222222222");
}
public A(){
System.out.println("3333333333333");
}
}
执行结果如下
代码块小结
- 静态代码块在类加载的时候就执行,且只执行一次
- 实例代码块在对象初始化的时候运行,且只执行一次
- 所以对于实例代码块每创建一个对象就执行一次
- 代码块都遵循自上而下的顺序执行
- 对象创建之前,因为调用了父类的结构,所以会加载父类,所以最先执行的是静态代码块,会在类加载的时候执行
- 后面的实例代码块则是在执行构造器的时候执行