static,final,abstract
static关键字
修饰符---变量,方法,代码块,内部类
静态变量:静态变量会随着类加载(方法区的静态常量池),加载到方法的静态方法区,类变量与类同级,提供了可以通过类名点的形式调用静态变量,也可以通过对象调用,创建的所有对象都会共享这个静态变量
静态变量可以定义在普通方法中?--------不可以,方法只有被加载的时候才加载执行里面的内容
静态变量可以定义在构造方法中?---------不可以,静态变量与类同级,构造方法与对象同级
.java文件 ---》 编译---》.class文件 —-》classLoader 类加载器------》方法区---》放到静态方法区(被static修饰,有初始值)
修饰变量:
public class Text { public static void main(String[] args) { Person p1 = new Person(); p1.name="黄蓉"; p1.age = 20; p1.gender = '女'; System.out.println(p1.toString()+"\r"); Person p2 = new Person(); p2.name="郭靖"; p2.age = 30; p2.gender = '男'; System.out.println(p1.toString()); System.out.println(p2.toString()); } } class Person { // 属性 String name; static char gender; int age; public String toString(){ return this.name+","+this.age+","+this.gender; } }
修饰方法(静态方法):
静态方法随着类的加载(方法区的静态常量池)而加载,方法区的静态区,类方法与类同级,不会对静态方法赋予系统默认初始值,静态方法被调用时是被加载到栈中执行。可以被类点名调用,也可以通过对象调用。
静态方法中,可以定义静态变量吗?---------------不可以,静态方法被调用的时候,里面的内容才被加载执行。
静态方法中可以使用 this 吗? ———————不可以,因为静态方法与类同级,this与对象同级。
main方法可以直接调用其他的非静态变量或方法吗?----------------不可以
静态修饰的内容只能直接调用静态信息,非静态的内容可以直接调用静态信息和非静态信息
System.arraycopy()
Arrays.copyOf()
Arrays.toString()
Arrays.sort()
静态方法可不可以重载:可以
静态方法可不可以重写:不可以 ---------@Override-------下面的方法是重写,通过可以@Override验证
父子类允许出现方法签名一致的静态方法,但不是重写(不能出现子类父类方法签名一致,但是一个静态一个非静态的方法)
重写——–多态体现--------运行时针对的是对象
静态方法针对的是类
父子类不能出现方法签名一致,一个Static ,一个非Static
/* 父子类不能出现方法签名一致,一个Static ,一个非Static */ public class Text { } class sd{ public static void m(){ //------------- } } class sd1 extends sd{ public void m(){ //--------------错误 } }
两个父子类中出现两个方法签名一致的Static方法,但不是重写
public class Text { } class sd{ public static void m(){ } } class sd1 extends sd{ public static void m(){ //-------不是重写 } }
修饰代码块(静态代码块):
在方法外,类内,与类同级,优先于构造代码块执行,只加载一次(所有static加载的信息都只加载一次)
执行顺序(类(静态代码块,静态变量,静态方法)---->对象(构造代码块(与属性同级),构造方法)
父子间执行的顺序:父类静态-----》子类静态------》父类对象------》子类对象
public class Text { public static void main(String[] args) { SD d1 = new SD(); SD d2 = new SD(); } } class SD { static int K = 1; // 构造代码块 { System.out.println("构造代码块"); } // 静态代码块 static { K = 2; System.out.println("静态代码块"); } // 构造方法 public SD() { System.out.println("这是构造方法"); } }
题目:
public class Text { public static void main(String[] args) { System.out.println(new SD().i); //输出为 6 } } class SD { int i=1; { i+=5; } } /*java检测到一个成员变量,创建对象,往下执行构造代码块,i由1变为了2,最后输出的结果就是2*/ //------------------------------------------------------------ public class Text { public static void main(String[] args) { System.out.println(new SD().i); //结果 1; } } class SD { { i=5; } int i =1; } /*java 检测到一个变量是i,值为5,没有检测到关于变量i的定义(检测上下文),先把这个变量i,标记成成员变量,往下继续找关于i的定义,由于只是成员变量的标记,所以只能赋值不能做任何其他操作,知道往下找到了和i同名的变量的定义,会先将标记值给这个定义,给完之后变量i才开始进行初始化*/ //---------------------------------------------------------- public class Text { public static void main(String[] args) { System.out.println(SD.x + " " + SD.y); } } class SD { /* * 先加载 执行第一句 执行第二句 执行第三句 * s NULL 0x0101 0x0101 0x0101 * x 0 1 1 1 * y 0 1 1 3 */ static SD s = new SD(); static int x; static int y = 3; public SD() { x++; y++; } } //---------------- public class Text { public static void main(String[] args) { System.out.println(new SD().x + " " + new SD().y); } } class SD { /* * 先加载 执行第一句 执行第二句 执行第三句 * s NULL 0x0101 0x0101 0x0101 * x 0 1 1 1 * y 0 1 1 3 */ static SD s = new SD(); //SD s = new SD();------死循环 static int x; static int y = 3; public SD() { x++; y++; } }
关键字 修饰符-----数据,方法,类
修饰数据(最终值):局部变量可以不给值,成员变量一定要给值
如果被修饰的是基本数据类型,值不能改变
如果修饰的是引用数据类型,地址值不能改变,元素值可以改变
数组的长度,被final修饰,不能改变
如果修饰的是属性,要保证在创建对象之前给值,如果被final和static共同修 饰(静态常量),要保证在类加载之前给值
public class Text { public static void main(String[] args) { final int i=1; //基本数据类型被final修饰只能被赋值一次 // i++; System.out.println(i); } } //------------------ package test; public class Text { public static void main(String[] args) { final int i=1; //引用类型 final int[] arr ={1,5,3}; arr[0]=3; //可以改变元素值 System.out.println(arr[0]); } } //--------------------------- public class Text { } class FDemo{ //final修饰的属性,需要保证在创建对象之前要给值 final int i; { i=1; } // public FDemo(){ // i=2; 两种选择一种 // } } //----------------------------- /*如果修饰的是属性,要保证在创建对象之前给值,如果被final和static共同修 饰(静态常量),要保证在类加载之前给值*/ public class Text { } class FDemo { // final修饰的属性,需要保证在创建对象之前要给值 final static int i; static { i = 1; } }
修饰方法(最终方法)
被final修饰的方法可以重载吗? 可以重载
被final修饰的方法可以重写吗? 不可以重写
修饰类(最终类)
final修饰的类可以被继承吗? 不能被继承,但是可以有父类
public class Text { } class FDemo { final public void m(){ } } final class FDemo1 extends FDemo{ }
abstract(抽象)
修饰方法,修饰类
所有子类对父类的某个方法都进行了不同程度的重写,这个父类方法体就没有意义,把方法体去掉,用abstract 修饰,就变成了抽象方法,一个类中出现了抽象方法,这个类就变成了抽象类
普通类继承抽象类,要重写父类所有的抽象方法;
抽象类继承抽象类,不需要重写父类所有的抽象方法;
抽象类必须有抽象方法? 不一定
抽象类可以创建对象? 不可以,底层c语言可以根据构造方法创建对象,但是拿不到
抽象方法可以被private,static,final修饰吗? 不能,因为抽象方法必须重写
抽象类可以被final修饰吗? 不可以,因为抽象类,可以被继承
//图形类 abstract class Shape{ //属性--长和宽 private double x; private double y; public double getX() { return x; } public double getY() { return y; } //有参构造给值 public Shape(double x,double y){ this.x=x; this.y=y; } //抽象方法周长 public abstract double getGirth(); } //矩形类 class Rectangle extends Shape{ public Rectangle(double x, double y) { super(x, y); } //周长 @Override public double getGirth() { return 2*(getX()+getY()); } public double getArea() { return getX()*getY(); } }