b、静态的东西可以去访问静态的东西
c、非静态的东西可以去访问静态的东西:
就相当于对象级别可以去访问类级别的,也就是说相当于子类可以去访问父类的东西,子类可以看成是对象级别的,父类看成类级别的
d、非静态的东西可以去访问非静态的东西
类的加载:
类级别的东西不能去访问对象级别的东西
属于类级别的有:一个是类,另外一个是静态属性和方法以及静态的代码块
属于对象级别的有:一个是非静态属性和方法,一个是构造方法,一个是非静态的代码块
先后顺序:类是先产生的,对象是在类产生之后才产生的。
public class Super {
String name = "JUN";
static int age = 21;
//非静态的代码块 :对象级别的东西
{
System.out.println("super中的非静态代码块");
//非静态代码块去调用非静态的属性:属性的位置必须放在非静态代码块的前面
System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
//构造器:也是对象级别的东西
public Super(){
System.out.println("super中的构造方法");
System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
public static void fun(){
System.out.println("super中的fun方法");
}
public static void fun2(){
System.out.println("super中的fun2方法");
}
public static void main(String[] args){
//1、通过对象的引用去访问
/**
* 调用构造器之前需要去加载非静态的代码块
*/
Super sup = new Super();
sup.fun();
sup.fun2();
}
}
|
运行结果:
super中的非静态代码块
JUN
21
-----------------
super中的构造方法
JUN
21
-----------------
super中的fun方法
super中的fun2方法
通过对象的引用去调用这两个方法,先是执行非静态代码块(对象级别),再执行构造方法(对象级别),再执行fun()和fun2(),从中就可以看到类的各个方法的加载循序,先是非静态代码块-----构造方法---调用的方法。
public class Super {
String name = "JUN";
static int age = 21;
//非静态的代码块 :对象级别的东西
{
System.out.println("super中的非静态代码块");
System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
//构造器:也是对象级别的东西
public Super(){
System.out.println("super中的构造方法");
System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
public static void fun(){
System.out.println("super中的fun方法");
}
public static void fun2(){
System.out.println("super中的fun2方法");
}
public static void main(String[] args){
//2、通过类名访问
Super.fun();
Super.fun2();
}
}
|
执行结果:
super中的fun方法
super中的fun2方法
类级别的东西不能调用对象级别的东西,所以通过类名的直接调用静态的方法不能加载非静态代码块和构造方法。
public class Super3 {
String name = "JUN";
static int age = 28;
public static void fun(){
System.out.println("super3中的fun方法");
}
//非静态的代码块 :对象级别的东西
{
System.out.println("super3中的非静态代码块");
//非静态代码块去调用非静态的属性:属性的位置必须放在非静态代码块的前面
// System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
//静态代码块:类级别的东西
static{
System.out.println("super3的静态代码块");
//name为非静态的,所以在静态代码块不能访问System.out.println(name);
System.out.println(age);
System.out.println("--------------------------");
}
//构造器:也是对象级别的东西
public Super3(){
System.out.println("构造方法");
System.out.println(name);
System.out.println(age);
System.out.println("--------------");
}
public static void main(String[] args){
//1、通过对象的引用去访问
/**
* 调用构造器之前需要去加载非静态的代码块
* 加载的顺序:非静态代码块-----构造器----方法的内容
*/
Super3 sup = new Super3();
sup.fun();
}
}
|
运行结果:
super3的静态代码块
28
--------------------------
super3中的非静态代码块
28
-----------------
构造方法
JUN
28
--------------
super3中的fun方法
通过对象级别的东西能调用类级别和对象级别的东西,加载的顺序是静态代码块----非静态代码块---构造方法---被调用的方法。(现有类再有对象,所以是先有类级别的(静态代码块)才有对象级别的(非静态代码块))
public class Super3 {
String name = "JUN";
static int age = 28;
public static void fun(){
System.out.println("super3中的fun方法");
}
//非静态的代码块 :对象级别的东西
{
System.out.println("super3中的非静态代码块");
//非静态代码块去调用非静态的属性:属性的位置必须放在非静态代码块的前面
// System.out.println(name);
System.out.println(age);
System.out.println("-----------------");
}
//静态代码块:类级别的东西
static{
System.out.println("super3的静态代码块");
//name为非静态的,所以在静态代码块不能访问System.out.println(name);
System.out.println(age);
System.out.println("--------------------------");
}
//构造器:也是对象级别的东西
public Super3(){
System.out.println("构造方法");
System.out.println(name);
System.out.println(age);
System.out.println("--------------");
}
public static void main(String[] args){
//2、通过类名访问
/**
* 加载的顺序:加载静态代码块再,加载本方法的内容:
* 原因是类级别的东西不会加载对象级别的,所以非静态代码块和构造器都不
* 加载
*/
Super3.fun();
}
}
|
运行结果:
super3的静态代码块
28
--------------------------
super3中的fun方法
类级别的东西只能加载类级别的东西,所以只加载静态代码块和本方法
从上面可以得出,通过对象级别(对象的引用)去调用某方法,加载的顺序是:
加载静态代码块-------加载非静态代码块----加载构造器------加载该方法
通过类级别(类名调用静态方法),加载的顺序是:
加载静态代码块-------加载该方法
在有继承情况下的加载顺序
父类:
public class StaticDemo {
String name="JUN";
static int age=20;
{
System.out.println("加载父类非静态的代码块");
}
static{
System.out.println("加载父类静态的代码块");
}
public StaticDemo(){
System.out.println("加载父类StaticDemo的构造方法");
}
public void fun(){
System.out.println("加载父类fun方法");
}
}
|
子类:
public class StaticDemo3 extends StaticDemo{
{
System.out.println("加载子类非静态的代码块");
}
static{
System.out.println("加载子类静态的代码块");
}
public StaticDemo3(){
System.out.println("加载子类的StaticDemo3的构造方法");
}
public static void fun(){
System.out.println("加载子类fun方法");
}
public static void main(String[] args){
StaticDemo3 sta = new StaticDemo3();
sta.fun();
}
}
|
通过对象的引用(对象级别)去调用静态的方法,用继承情况下的加载顺序:
(运行结果)
加载父类静态的代码块
加载子类静态的代码块
加载父类非静态的代码块
加载父类StaticDemo的构造方法
加载子类非静态的代码块
加载子类的StaticDemo3的构造方法
加载子类fun方法
子类2:
public class StaticDemo3 extends StaticDemo{
{
System.out.println("加载子类非静态的代码块");
}
static{
System.out.println("加载子类静态的代码块");
}
public StaticDemo3(){
System.out.println("加载子类的StaticDemo3的构造方法");
}
public static void fun(){
System.out.println("加载子类fun方法");
}
public static void main(String[] args){
StaticDemo3.fun();
}
}
|
通过类名调用静态的方法(类级别调用),只能加载类级别的东西
运行结果:
加载父类静态的代码块
加载子类静态的代码块
加载子类fun方法
非静态的代码块的用处:(精简代码)
比如你要用jdbc做增删改查的功能,增删改的方法和查询的方法这2个方法都要导入数据库驱动,也需要建立连接,也需要执行的是sql语句,这些都是公共的东西为了使得代码精简,就将这些在不同方法里面相同的东西提取出来放在非静态的代码块里面去。