一、主函数
主函数:是一个特殊的函数,座位程序的入口,可以jvm调用。
主函数的定义“
public:代表该函数访问权限是最大的
static:代表主函数随着类的加载就已经存在了
void:主函数没有具体的返回值
main:不是关键字,丹斯是一个特殊的单词,可以被jvm识别
(String[] args):函数的参数,参数类型是一个数组,该数组中的元素是字符串,字符串类型的数组
主函数是固定格式的,jvm识别
jvm在调用主函数时,传入的时new String(0);
public static void main(String[] args)
class MainDemo
{
/*
public static void main(int x)//重载
{
}
*/
public static void main(String[] args)//只有args是可以改的,传入的要嘛是数组,要嘛空
{
//System.out.println(args.length);
//System.out.println(args[0]);
String[] arr = ("ha","hei","hia");
MainTest.main(arr);
}
}
class MainTest
{
public static void main(String[] args)
{
for(int x=0; x<arr.length;x++)
System.out.println(args[x]);
}
}
什么时候使用静态?
要从两个方面下手:
因为静态修饰的内容有成员变量和函数。
什么时候定义静态变量(类变量)呢?
当对象中出现共享数据时,改数据被静态所修饰
对象中的特有数据要定义成非静态存在堆内存中
什么时候定义静态函数呢?
当功能内部没有访问到非静态数据(对象的特有数据),
那么该功能可以定义成静态的
class Person
{
String name;
public static void show()//当功能内部没访问到非静态数据(对象的特有数据)
{
System.out.println("haha");
}
/*
public void show()//有访问到非静态不可定义成静态
{
System.out.println(name+"haha");
}
*/
}
class MainTest
{
public static void main(String[] args)
{
//Person p = new Person();
//p.show
person.show();
}
}
二、静态代码块
格式
static
{
静态代码块中的执行语句;
}
特点:随着类的加载而加载,只执行一次,并优先于主函数,用于给类初始化的
静态代码块:用staitc声明,jvm加载类时执行,仅执行一次
构造代码块:类中直接用{}定义,每一次创建对象时执行。
执行顺序优先级:静态代码块>mian方法>构造代码块>构造函数>普通代码块
class StaticCode
{
int num = 9;
StaticCode()
{
System.out.println("e");//空参数构造函数给对应对象初始化
}
static
{
System.out.println("a");//静态代码块给类初始化
//System.out.println("a"+num);不能访问num,num是非静态成员
}
{
System.out.println("c"+num);//构造代码块给对象初始化,可以访问num
}
public static void show()
{
System.out.println("show run");//普通代码块(一般方法)
}
}
class StaticCodeDemo
{
static
{
System.out.println("b"); //第一步,先加载主函数所在类,所以先加载并执行这段静态代码块。
}
public static void main(String args[])
{
new StaticCode(); //第三步,加载StaticCode类
new StaticCode();//第四步,类只加载一次,静态代码块只执行一次,不再执行静态代码块
System.out.println("over");//第五步,输出打印,结果 b c a over
//StaticCode.show();//类名调用静态方法,不一定要有对象。输出结果a(静态代码块),show run(普通函数)
}
static
{
System.out.println("c");//第二步,多个静态代码块,按先后顺序执行
}
}
class StaticCode
{
static
{
System.out.println("a");//静态代码块给类初始化
//System.out.println("a"+num);不能访问num,num是非静态成员
}
{
System.out.println("c"+num);//构造代码块给对象初始化,可以访问num
}
StaticCode(int x)
{
System.out.println("d");//有参数的构造函数给对应对象初始化
}
}
class StaticCodeDemo
{
public static void main(String args[])
{
new StaticCode(4);//输出结果a(静态代码块) c9(构造代码块) d(有参数的构造函数)
//StaticCode s = null;//无实体指向,不加载静态代码块
//s = new StaticCode();//构造函数,运用到类的内容时,才涉及到加载静态代码块的问题
}
}
三、对象的初始化过程
class Person
{
private String name;//第四步:默认初始化null,第五步:如果有值就显示具体值
private int age;
private static String country = "cn";
static
{
System.out.println("name"+name+"age"+age);//第二步,静态初始化
}
{
System.out.println("name"+name+"age"+age);//第六步:构造代码块初始化
}
Person(String name,int age)
{
this.name = name;//第七步:构造函数初始化
this.age = age;
}
public void setName(String name)
{
this.name = name;
}
public void speak()
{
System.out.println(this.name+"...."+this.age);
}
public static void showCountry()
{
System.out.println("country"+country);
}
}
class PersonDemo
{
public static void main(String[] args)
{
Person p = new Person("zhangsan",20);
p.speak();
}
}
Person p = new Person("zhangsan",20);
该句话都做了什么事情?
1.因为new用到了Person.class类,所以会先找到Person.class文件并加载到内存中
2.执行该类中的static代码块,如果有的话,给Person.class进行初始化
3.在堆内存中开辟空间,分配内存地址
4.在堆内存中建立对象的特有属性,并进行默认初始化。
5.对属性进行显示初始化。
6.对对象进行构造代码块初始化
7.对对象进行对象的构造函数初始化
8.将内存地址赋给栈内中的p变量










网友评论