1.类变量与实例变量
- 我是这么理解的:类变量就是可以直接使用类名来访问(用static修饰)当然也可以使用对象来访问,实例变量则需要通过创建实例来访问。
- 类变量属于类,实例变量属于对象,不同对象的实例变量有不同的存储空间,而该类所有对象共享同一个类变量空间。
public class A {
static int q;
int b;
A(int b){
this.b=b;
q++;
}
public static void main(String args[]){
A a1=new A(10);
A a2=new A(11);
System.out.println("实例变量为:");
System.out.println("a1.b="+a1.b);
System.out.println("a2.b="+a2.b);
System.out.println("类变量为:"+A.q);
System.out.println("a1.q="+a1.q);
System.out.println("a2.q="+a2.q);
}//一个对象对类变量的修改会影响到其他类
}
2.类方法和实例方法
与变量一样。类方法不能访问实例变量,而实例方法能访问实例变量和类变量。
static修饰的方法在类实例化之前就已经被分配了内存,因此抽象类中的不能由静态的抽象方法。
在Java中,如果父类中含有一个静态方法,且在子类中也含有一个返回类型、方法名、参数列表均与之相同的静态方法,那么该子类实际上只是将父类中的该同名方法进行了隐藏,而非重写。换句话说,父类和子类中含有的其实是两个没有关系的方法,它们的行为也并不具有多态性。调用这个方法时根据引用类型来决定是调用父类还是子类的方法.(父类的引用则调用父类的方法)。
示例
class A{
static int i=1;
public static void aa(){
System.out.println("父类的static方法");
System.out.println(i);//类变量可以直接调用或者使用类名。变量名。
}
//public int bb(){
//static int b=9; static不能修饰局部变量。
//}
}
class B extends A{
public static void aa(){
System.out.println("子类的static方法");
}
}
public class StaticTest{
public static void main(String args[]){
A t1=new B();//这里t1时父类的引用类型
t1.aa();//这里调用的是父类的aa()方法。
B t2=new B();//这里t2是子类的引用类型。
t2.aa();//这里调用的是子类的aa()方法。
}
}
3.静态代码块
static除了修饰变量和方法外还可以修饰类中的代码块称为静态代码块
非静态代码块用于实例变量的初始化,在对象被创建的时候调用,类每创建一次非静态代码块就会执行一次。
实例变量的初始化分为四部
1 :用new运算符给实例变量分配空间时的默认初始化!
2:类定义中的显示初始化!
3 :非静态代码块的初始化!
4:执行构造方法进行初始化!
示例
public class StaticBlockTest {
int i=2;
static int is;
//静态初始化程序
static{
System.out.println("in static block");
is=5;
System.out.println("static variable is="+is);
}
{
//非静态初始化在创建对象时才被调用!(用于实例变量的初始化!)
System.out.println("in non-static block!");
i=8;
}
i=10;
}
public static void main(String args[]){
System.out.println("in main()");
StaticBlockTest s=new StaticBlockTest();//此时非静态初始化被调用!
StaticBlockTest a=new StaticBlockTest();//类每创建一次对象就会为实例变量分配一次内存空间(非静态代码块就会执行一次)
System.out.println(s.i);
}//静态初始化程序在类加载时执行且执行一次!静态初始化优于主方法!
}//main方法在哪个类先执行哪个类!
加个继承的示例
class A{
{
System.out.println("非静态代码1");
}
public A(){
System.out.println("构造1");
}
}
class B{
static{//1.执行静态代码块
System.out.println("静态代码1");
}
{
System.out.println("非静态代码2");
}
public B(){
System.out.println("构造2");
}
}
class StaticTest extends B{
public static void main(String args[]){//2.执行main()方法
System.out.println("hello");//3.执行这个
new StaticTest();//4.创建对象分为:默认初始化;显示初始化;执行非静态代码块;执行构造方法。
System.out.println("hi");//5.输出这个。
}
}
这里需要注意/////////////////////////////////////////
public class StaticVariable {
int a=2;
{
a=8;
System.out.println("这里是非静态代码块!");
}
static{
System.out.println("这里是静态代码块!");
}public static void main(String args[]){
StaticVariable s=new StaticVariable();
System.out.println(s.a);
}//此时输出结果a=8;
}
//{
// a=8;
// System.out.println("这里是非静态代码块!");
//}
//int a=2;
//此时输出结果是a=2;
只要记得谁在下面谁厉害!(静态代码块初始化的类变量也是一样的规则!)
具体原因我也说不上来 = = 求大神指点!