main方法
* main()方法的使用说明 * main方法是程序的主入口(一个主程序 先从main开始进行执行) * * * main方法也可以是一个普通的静态方法
由于Java虚拟机需要调用类的main()方法,所以该方法的访问权限必须是 public,又因为Java虚拟机在执行main()方法时不必创建对象,所以该方法必须 是static的,该方法接收一个String类型的数组参数,该数组中保存执行Java命令
时传递给所运行的类的参数。
又因为main() 方法是静态的,我们不能直接访问该类中的非静态成员,必须创
建该类的一个实例对象后,才能通过这个对象去访问类中的非静态成员,这种情
况,我们在之前的例子中多次碰到。
代码块
代码块也是类的成员变量之一, 分为静态代码块和非静态代码块
static{ // 静态代码块 } //非静态代码块 { }
* 类的成员之四: 代码块(或初始化代码块) 类的成员: 属性 方法 ,构造器 ,代码块 * <p> * <p> * 1. 代码块的作用: 用来初始化类或对象 * 2. 代码块如果有修饰的话, 只能使用static * 3. 分类: 静态代码块,非静态代码块
eg:
public class CodeBlock { public static void main(String[] args) { String desc = BlockPerson.desc; // 当我是静态代码块 BlockPerson blockPersonOnew = new BlockPerson(); //我是非静态代码块 } } class BlockPerson { String name; int age; static String desc = "我是一个人"; //构造器 public BlockPerson() { } public BlockPerson(String name, int age) { this.name = name; this.age = age; } //代码块 static{ //静态代码块 随着类的加载而加载 System.out.println("我是静态代码块"); } { //非静态代码块 System.out.println("我是非静态代码块"); } @Override public String toString() { return "Person[ name:"+name+"age:"+age+"]"; } public static void info(){ System.out.println("我是一个人"); } }
非静态代码块可调用静态的方法和属性
{ //非静态代码块 System.out.println("我是非静态代码块"); age = 1; desc = "我是一个爱学习的人"; //非静态代码块可以调用静态结构 info(); }
静态代码块和非静态代码块的区别
4. 静态代码: * > 内部可以有输出语句 * > 随着类的加载而执行,而且只执行一次 * > 初始化类的属性 * > 如果一个类中定义了多个静态代码块,按照声明的先后顺序执行 * > 静态代码块的执行要优先于非静态代码块执行(因为静态代码块是随着类的加载而执行,非静态是需要对象实例化后执行的) * >静态代码块内只能调用静态的属性和方法 不能调用非静态的 * 5. 非静态代码块 * > 内部可以有输出语句 * > 随着对象的创建而执行 * > 每创建一个对象就执行一次非静态代码块,只要类不重新加载就不会重新执行 * > 作用: 可以在创建对象是 对对象的属性赋值 * > 可以调用静态和非静态的属性和方法
对象赋值的方法:
对象赋值的方法: * 对属性可以赋值的位置: * 1. 默认初始化 * 2. 显示初始化 / 5. 在代码块中赋值(谁先写就先赋值谁) * 3. 构造器初始化 * 4. 有了对象之后, 可以通过"对象.属性" 或" 对象.方法" 赋值 顺序是: 1 >2 /5 > 3 >4
eg:
public class OrderTest { public static void main(String[] args) { Rder rder = new Rder(); System.out.println(rder.age); //4 } } class Rder{ int age = 3; // 显示赋值 { age = 4; } }
对象赋值的
面试题:
此处,Something类的文件名叫OtherThing.java class Something { public static void main(String[] something_to_do) { System.out.println("Do something ..."); } } 上述程序是否可以正常编译、运行?
结果:
可以编译运行,只不过无法输出语句 因为主类没有main方法主类没有执行
练习题:
说出以下内容的执行结果:
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);
} }
结果:
因为静态代码块是随着类的加载而执行 因为类的加载优先于对象的创建 所以先执行静态代码块中的输出语句,然后再输出下面对面的调用的属性 in static block total=100 total=100
下面题目的输出是:
//总结: 由父及子,静态先行 public class LeftTest { public static void main(String[] args) { new Left(); } } class Root { static { System.out.println("我是Root的静态代码块"); } { System.out.println("我是Root的非静态代码块"); } public Root() { System.out.println("我是Root的无参构造器"); } } class Mid extends Root{ static { System.out.println("我是Mid的静态代码块"); } { System.out.println("我是Mid的非静态代码块"); } public Mid() { System.out.println("我是Mid的无参构造器"); } public Mid(String msg){ this(); System.out.println("Mid的参数构造器,参数是:msg:"+msg); } } class Left extends Mid { static { System.out.println("我是Left的静态代码块"); } { System.out.println("我是left的非静态代码块"); } public Left() { System.out.println("我是left的无参构造器"); } public Left(String msg){ super(); System.out.println("我是Left的参数构造器,参数是msg:"+msg); } }
结果:
* 我是Root的静态代码块 * 我是Mid的静态代码块 * 我是Left的静态代码块 * 我是Root的非静态代码块 * 我是Root的无参构造器 * 我是Mid的非静态代码块 * 我是Mid的无参构造器 * 我是left的非静态代码块 * 我是left的无参构造器
下面的输出是:
class FatherTest { static { System.out.println("111111"); } { System.out.println(22222); } public FatherTest() { System.out.println(33333); } } public class SonTest extends FatherTest { static { System.out.println("44444444"); } { System.out.println("55555555"); } public static void main(String[] args) { System.out.println("777777777"); System.out.println("**********"); new SonTest(); System.out.println("+++++++++++"); new SonTest(); System.out.println("========"); new FatherTest(); } }
结果:
111111 44444444 777777777 ********** 22222 33333 55555555 +++++++++++ 22222 33333 55555555 ======== 22222 33333