⭐️引言⭐️
大家好啊,我是执梗。Java的学习非一朝一夕可以成功,需要我们水滴穿石般的坚持。每日进步一点点系列,旨在可以**每天只花几分钟就能学到Java中我们可能忽略的知识,同时也可以检验自己的Java能力**,**无论你是坐着躺着还是蹲着,花上几分钟时间就可以检验和巩固到自身的Java知识点**,希望能和大家每天都能进步一点点。
🍋1.Java代码初始化顺序
Java的语言中,当我们去实例化对象时(也就是通常说的new对象),对象所在类的所有成员变量首先都要被初始化,只有这个类所有成员变量完成初始化后,才会调用该类的构造方法去创建对象。
Java的初始化顺序一般都遵循着一下三个原则(从高到底):
** 1.静态对象(被static修饰的变量)优先于非静态对象初始化,而且静态对象只会被初始化一次,而非静态对象可能会多次初始化**
** 2.父类总是优先于子类初始化(就是当你实例化A类对象时,发现A类有个父类B类,我们必须得先初始化B了才能回来初始化A)**
**3.按照成本变量定义的顺序进行初始化。即使变量定义的很分散,它们仍然会按照从头到尾的顺序去完成初始化。**
但是Java程序的初始化工作可以在不同的代码块中来完成(比如:静态代码块、构造方法等),它们执行的顺序是一个非常总要的核心,执行的顺序为:
**父类静态变量->父类静态代码块->子类静态变量->子类静态代码块->父类非静态变量->父类非静态代码块->父类构造方法->子类非静态变量->子类非静态代码块->子类构造方法。 **
我们通过一个例子来帮助大家记忆:
public class Son extends father {
static {
System.out.println("子类静态代码块");
}
{
System.out.println("子类非静态代码块");
}
public Son() {
System.out.println("子类构造方法");
}
}
class father{
static {
System.out.println("父类静态代码块");
}
{
System.out.println("父类非静态代码块");
}
public father() {
System.out.println("父类构造方法");
}
}
下面是主函数和输出顺序:
public static void main(String[] args) {
new Son();
}
可以发现输出结果完全符合我们上面的顺序。其实这也非常好记忆,无论是子类还是父类,都是优先静态后非静态,子类除了静态代码块能紧跟父类静态代码块,其他全都是落后于父类执行。
☀️2.Java反射
Java为什么强大?我相信需要人都知道是由于Java的反射机制。**反射机制是指对于处在运行中的类,都能够获取到这个类的所有属性和方法**。对于任意一个对象,都能够调用它的任意一个以及访问它的属性;这种通过**动态获取类或对象的属性以及方法**从而完成调用功能就被称之为Java语言的反射。Java许多强大的框架,如ssm+springboot都是基于反射机制的强大而实现的。反射主要有以下四个功能:
获取类的访问修饰符、方法、属性以及父类信息
在运行时根据类的名字创建对象。可以在运行时调用任意一个对象的方法
在运行时判断一个对象属于哪个类
生成动态代理
Java中万物皆为类,反射中也存在一个非常非常重要的类——Class。在Java语言中获取Class对象的主要方法有以下几种:
1.通过className.class获取。通过类名.class直接获得Class对象
public class test {
public static void main(String[] args) {
Class<A> aClass = A.class;
System.out.println(aClass);
}
}
class A{
}
**2. 通过Class.forName()来获取**
public class test {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> a = Class.forName("wangdao5.A");
System.out.println(a);
}
}
class A{
}
我这里的wangdao5是我的包名,如果你使用这个方法时出现ClassNotFound的异常,在你的类名前加上包名即可。
**3.通过Object.getClass()来获取**
public class test {
public static void main(String[] args) throws ClassNotFoundException {
Class<?> a = new A().getClass();
System.out.println(a.getName());
}
}
class A{
}
上面就是我们常见的三种获取类的Class对象的方式,肯定有同学好奇这有啥区别呢?看上去感觉都差不多。别急,它们还是有区别的:
- 方法1不执行静态块和动态构造代码块
- 方法2只执行静态块,而不执行动态构造块
- 因为需要创建对象,所以会执行静态块和动态块
Class类之所以强大,是因为它提供了非常非常多的方法,下面给大家举例三类常用的方法。
**1.获取类的构造方法**
** **构造方法的封装类为Constructor,Class类中有如下四个方法来获得Constructor对象:
public Constructor<?>[] getConstructors():返回类的所有的public构造方法
public Constructor<T> getConstructor(Class<?>...parameterTypes):返回指定的public构造方法;
public Constructor<?>[] getDeclaredConstructors();返回类的所有的构造方法
public Constructor<T> getDeclaredConstructor(Class<?>...parameterTypes):返回指定的构造方法
2.获取类的成员变量的方法
成员变量的封装类为Field类,Class类提供了以下四个方法来获取Field对象:
public Field[] getFields():获取类的所有的public成员变量
public Field getField(String name):获取指定的public成员变量
public Field[] getDeclaredFields():获取类的所有的成员变量
public Field getDeclaredField(Strig name):获取任意访问权限的指定名字的成员变量
3.获取类的方法
public Method[] getMethods:获取所有的public方法
public Mehod[] getDeclaredMethods():获取所有的方法
public Method getDeclareMethod(Stirng name,Class<?>...parameterTypes)获取指定的方法
学习如同逆水行舟,不进则退!
每日进步一点点,水滴石穿!
看完如果让你进步了一点点,球球感谢给一个三连支持!!!
版权归原作者 执 梗 所有, 如有侵权,请联系我们删除。