image.png 前言 看到这个问题,马上就可以回答出来:因为抛出异常就会 crash。 那么为什么抛出异常就会 crash 呢? 有没有办法不让 App crash 呢?...接下来我们进入正题吧 先探讨一下第一个问题吧:为什么抛出异常就会 crash。...首先我们看下线程中抛出异常以后的处理逻辑吧: 一旦代码抛出异常,并且我们没有捕捉的情况下,JVM 会调用 Thread 的 dispatchUncaughtException 方法。...既然如此,那有没有其他办法可以保证 App 在抛出异常不 crash 的情况下,又能保证不会卡死呢?...既然 looper 是查询事件的核心类,那么我们是否可以不让跳出 loop 循环呢,乍一想好像没办法做到,我们没法给 loop 方法 try-catch 。
类方法和接口方法符号引用的常量类型是分开的。如果,在类方法中解析出来的是一个接口,则会抛出 IncompatibleClassChangeError 异常。...如果所属接口中匹配到目标方法,则返回此方法的直接引用。否则,在父接口中查找,若找到,则返回。否则,查找失败,抛出 NoSuchMethodError 异常。...由于父类的 方法先执行,所以父类的静态代码块也优于子类执行。 如果类中没有静态代码块,也没有为变量赋值,则可以不生成 方法。...另外,接口的实现类在初始化时也不执行接口的 方法。 虚拟机会保证在多线程环境下 方法能被正确的加锁、同步。...类的初始化时机:只有对类主动使用的时候才会触发初始化,主动使用的场景如下: 使用new关键词创建对象时,访问某个类的静态变量或给静态变量赋值时,调用类的静态方法时。
另一种异常是 OutOfMemoryError 异常,当虚拟机栈可以动态扩展时(当前大部分虚拟机都可以),如果无法申请足够多的内存就会抛出 OutOfMemoryError,如何制作虚拟机栈 OOM 呢...当堆无法再扩展时,会抛出 OutOfMemoryError 异常。 方法区 方法区存放的是类信息、常量、静态变量等。...为什么对 str2 比较返回的是 false 呢?这是因为,JVM 中内部在加载类的时候,就已经有"java"这个字符串,不符合 “首次出现” 的原则,因此返回false。...解析 解析阶段是把虚拟机中常量池的符号引用替换为直接引用的过程。 初始化 类初始化时类加载的最后一步,前面类加载过程中,除了加载阶段用户可以通过自定义类加载器参与以外,其余动作都是虚拟机主导和控制。...到了初始化阶段,才是真正执行类中定义 Java 程序代码。 准备阶段中,变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划初始化类变量。
同时,为了让 Spring 能够扫描类路径中的类并识别出 @Repository 注解,需要在 XML 配置文件中启用Bean 的自动扫描功能,这可以通过<context:component-scan/...Spring 在容器初始化时将自动扫描 base-package 指定的包及其子包下的所有 class文件,所有标注了 @Repository 的类都将被注册为 Spring Bean。...为什么 @Repository 只能标注在 DAO 类上呢?这是因为该注解的作用不只是将类识别为Bean,同时它还能将所标注的类中抛出的数据访问异常封装为 Spring 的数据访问异常类型。...Spring本身提供了一个丰富的并且是与具体的数据访问技术无关的数据访问异常结构,用于封装不同的持久层框架抛出的异常,使得异常独立于底层的框架。...如果这个注解不包含 name值或是其他被自定义过滤器发现的组件,默认 Bean 名称会是小写开头的非限定类名。如果你不想使用默认 bean命名策略,可以提供一个自定义的命名策略。
1.2 初始化时机 父类静态变量初始化 父类静态块初始化 子类静态变量初始化 子类静态块初始化 main方法执行 父类构造器初始化 子类构造器初始化 从结果中,我们可以看出两点: 父类的静态变量和静态块比子类优先初始化...被 static 修饰的方法,在类初始化的时候并不会初始化,只有当自己被调用时,才会被执行。...我们不需要初始化类就可直接使用静态变量; 我们在类中写个 main 方法运行,即便不写初始化类的代码,静态变量都会自动初始化; 静态变量只会初始化一次,初始化完成之后,不管我再 new 多少个类出来,静态变量都不会再初始化了...catch 中发生了未知异常,finally 还会执行么? 答:会的,catch 发生了异常,finally 还会执行的,并且是 finally 执行完成之后,才会抛出 catch 中的异常。...不过 catch 会吃掉 try 中抛出的异常,为了避免这种情况,在一些可以预见 catch 中会发生异常的地方,先把 try 抛出的异常打印出来,这样从日志中就可以看到完整的异常了。
我们还得从异常的源码开始说起: 一般情况下,一个应用中所使用的线程都是在同一个线程组,而在这个线程组里只要有一个线程出现未被捕获异常的时候,JAVA 虚拟机就会调用当前线程所在线程组中的 uncaughtException...这就要从APP的启动流程说起了,之前也说过,所有的Android进程都是由zygote进程fork而来的,在一个新进程被启动的时候就会调用zygoteInit方法,这个方法里会进行一些应用的初始化工作:...小光的再次思考(拦截主线程崩溃的方案思想) 我们都知道,在主线程中维护着Handler的一套机制,在应用启动时就做好了Looper的创建和初始化,并且调用了loop方法开始了消息的循环处理。...而在execute方法中。。。咦咦咦,这不就是token吗?...可能有的朋友会问,为什么要让程序不崩溃呢?会有哪些情况需要我们进行这样操作呢?
当堆无法再扩展时,会抛出OutOfMemoryError异常。 方法区 方法区存放的是类信息、常量、静态变量等。...为什么对str2比较返回的是false呢?这是因为,JVM中内部在加载类的时候,就已经有"java"这个字符串,不符合“首次出现”的原则,因此返回false。...那么那些对象可作为GC Roots呢?主要有以下几种: 1.虚拟机栈(栈帧中的本地变量表)中引用的对象。 2.方法区中类静态属性引用的对象。...解析 解析阶段是把虚拟机中常量池的符号引用替换为直接引用的过程。 初始化 类初始化时类加载的最后一步,前面类加载过程中,除了加载阶段用户可以通过自定义类加载器参与以外,其余动作都是虚拟机主导和控制。...到了初始化阶段,才是真正执行类中定义Java程序代码。 准备阶段中,变量已经赋过一次系统要求的初始值,而在初始化阶段,根据程序员通过程序制定的主观计划初始化类变量。
,我们根据执行逻辑,如果有static{}和构造方法,我们可以看一眼里面除了初始化是否还有别的东西,这里并没有这两个调用,我们直接去onCreate方法中,这个Acitivity创建时调用的方法 分析代码...,这个类分析到这,不是什么重要的类,接着往下看 public void onCreate(Bundle bundle) { super.onCreate(bundle);...,在Jadx-Gui中右键->Find Usage找到方法定义的地方,可以从中文字符看出我们找到了主要逻辑,我们的目的就是打印出正确二字,从这个逻辑中可以看出,我们必须保证this.b.check不能抛出异常才行...(this.b).setMessage("错误").setNeutralButton("OK", null).create().show(); } } check 我们必须保证不抛出异常...,然后我用androidkiller打开这个apk文件,看汇编代码发现这个getKey不是调用M类中的方法,因为是个乱码,实际上是调用了父类中继承的方法 iArr = [0, 3, 13, 19, 85
B).如果将变量或者方法声明为final,可以保证它们在使用中不被改变. 1)被声明为final的变量必须在声明时给定初值,而在以后的引用中只能读取,不可修改。 ...被final修饰的变量必须被初始化。初始化的方式以下几种: 1.在定义的时候初始化。 2.final变量可以在初始化块中初始化,不可以在静态初始化块中初始化。...3.静态final变量可以在定义时初始化,也可以在静态初始化块中初始化,不可以在初始化块中初始化。 4.final变量还可以在类的构造器中初始化,但是静态final变量不可以。...语句块”); } } } 复制代码 运行结果说明了finally的作用: 1.程序抛出了异常 2.执行了finally语句块请大家注意,捕获程序抛出的异常之后,既不加处理,也不继续向上抛出异常,并不是良好的编程习惯...finalize()方法是在GC清理它所从属的对象时被调用的,如果执行它的过程中抛出了无法捕获的异常(uncaughtexception,GC将终止对改对象的清理,并且该异常会被忽略;直到下一次GC开始清理这个对象时
我们还得从异常的源码开始说起: 一般情况下,一个应用中所使用的线程都是在同一个线程组,而在这个线程组里只要有一个线程出现未被捕获异常的时候,JAVA 虚拟机就会调用当前线程所在线程组中的 uncaughtException...这就要从APP的启动流程说起了,之前也说过,所有的Android进程都是由zygote进程fork而来的,在一个新进程被启动的时候就会调用zygoteInit方法,这个方法里会进行一些应用的初始化工作:...小光的再次思考(拦截主线程崩溃的方案思想) 我们都知道,在主线程中维护着Handler的一套机制,在应用启动时就做好了Looper的创建和初始化,并且调用了loop方法开始了消息的循环处理。...而在execute方法中。。。咦咦咦,这不就是token吗?...但是这种办法要适配不同SDK版本的源码才行,所以慎用,需要的可以看文末Cockroach库源码。 可能有的朋友会问,为什么要让程序不崩溃呢?会有哪些情况需要我们进行这样操作呢?
相应的,我们的数据在没有额外处理的情况下,往往也会被初始化,然后在界面重启时重新加载。 但如果当前页面需要维护某些状态不被丢失呢,比如 选择、上传状态 等等? 此时问题就变得棘手起来。...从而我们可以利用 SavedStateHandle 以key-value的形式去保存一些 自定义状态 ,从而在进程异常终止,Act重建后,也能获取到之前保存的状态。 至于为什么能实现保存状态呢?...从而在我们 Activity 异常重建时做到状态的 恢复 与 **绑定 ** (通过重写 onSavexx() 与 onCreate() 方法监听)。...create(modelClass,extras) 具体的创造逻辑里,这里的 factory 正是我们在 ViewModelProvider 初始化时,默认构造函数 defaultFactory() 方法中生成的...当我们的 Activity 重建完成后,在 onCreate() 方法中,再使用 SavedStateRegistry 还原我们自己保存的状态 restoredState。
: (1)ArrayBlockingQueue初始化时必须传入容量,也就是数组的大小; (2)可以通过构造方法控制重入锁的类型是公平锁还是非公平锁; 入队 入队有四个方法,它们分别是add(E e)、offer...public boolean add(E e) { // 调用父类的add(e)方法 return super.add(e);} // super.add(e)public boolean...(3)入队和出队各定义了四组方法为满足不同的用途; (4)利用重入锁和两个条件保证并发安全; 彩蛋 (1)论BlockingQueue中的那些方法?...BlockingQueue是所有阻塞队列的顶级接口,它里面定义了一批方法,它们有什么区别呢?...,那是不是可以借助分段的思想把入队出队分裂成两个锁呢?
被final修饰的变量必须被初始化。初始化的方式有以下几种: 在定义的时候初始化。 final变量可以在初始化块中初始化,不可以在静态初始化块中初始化。...静态final变量可以在静态初始化块中初始化,不可以在初始化块中初始化。 final变量还可以在类的构造器中初始化,但是静态final变量不可以。...不过子类仍然可以定义同父类中的 private方法具有同样结构的方法,但是这并不会产生重写的效果,而且它们之间也不存在必然联系。 最后我们再来回顾一下final用于类的情况。...: 程序抛出了异常 执行了finally语句块 请大家注意,捕获程序抛出的异常之后,既不加处理,也不继续向上抛出异常,并不是良好的编程习惯,它掩盖了程序执行中发生的错误,这里只是方便演示,请不要学习。...finalize()方法是在GC清理它所从属的对象时被调用的,如果执行它的过程中抛出了无法捕获的异常(uncaught exception),GC将终止对改对象的清理,并且该异常会被忽略;直到下一次GC
那么,为什么我们还倾向于使用lodash的map函数?反对的至为关键理由是: lodash的map函数将可能的异常吃掉了! 这里提及的异常,指进行map的数组可能是undefined。...当声明的变量还未被初始化时,变量的默认值为undefined。Null类型的值为null,用来表示尚未存在的对象。...当然,在ECMAScript中,它认为undefined其实是从null派生出来的,换言之,它是null的一种特例。 再来看JS中的数组。...JS的数组从本质上讲就是一个对象,即Array对象,其作用是存储一系列的值。当我们声明了一个数组变量,却没有进行初始化时,就可能出现undefined的数组对象。...如果我们将未初始化的数组视为意外而抛出异常,就产生了我们不期望看到的副作用。显然,异常的抛出玷污了纯函数的纯洁无暇。 窃以为:错误是一种意外,却不能成为玷污的合法理由。
,这样理解起来会很轻松 简介 Executor是线程池的核心框架; 和它相对应的有一个辅助工厂类Executors,这个类提供了许多工厂方法,用来创建各种各样的线程池,下面我们先看下几种常见的线程池 /...线程池的底层类 ThreadPoolExecutor 在文章开头创建的几个线程池,内部都是有调用ThreadPoolExecutor这个类的,如下所示 public static ExecutorService...,遵循FIFO,尾部插入,头部获取 初始化时需指定队列的容量 capacity 类比到上面的场景,就是椅子的数量为初始容量capacity LinkedBlockingQueue: 链表阻塞队列,这是一个无界队列...,遵循FIFO,尾部插入,头部获取 初始化时可不指定容量,此时默认的容量为Integer.MAX_VALUE,基本上相当于无界了,此时队列可一直插入(如果处理任务的速度小于插入的速度,时间长了就有可能导致...) // 这里需要注意的是,抛出异常后,代码并不会退出,而是卡在异常这里,包括主线程也会被卡住(这个是默认的拒绝策略) // 我们可以用其他的拒绝策略
Java中变量的初始化顺序 在写一个通用的报警模块时,遇到一个有意思的问题,在调用静态方法时,发现静态方法内部对静态变量引用时,居然抛出了npe,仿佛是因为这个静态变量的初始化在静态方法被调用时,还没有触发...静态变量初始化顺序 类初始化时,会优先初始化静态成员,那么一个类中有多个静态成员时,如何处理的? 下面是一个使用静态成员,静态代码块,静态方法的测试类,那么下面的输出应该是怎样的呢?...那么第二个问题来了,前面说到哪个问题是什么情况 最开始说到,在调用类的静态方法时,发现本该被初始化的静态成员,依然是null,从上面的分析来说,唯一的可能就是在成员变量初始化的过程中,出现了异常 那么...初始化异常时 理论上,类初始化中抛出了异常,那么这个类将无法被classLoader正确的加载,因此也无法有效的使用这个类 但是不排除某些情况下,依然强行的使用了这个类(如上面gif图中的演示),这个原理还不太清晰...注意 因此,请格外注意,在初始化代码中,请确保不会有抛出异常,如果无法把控,不妨新建一个init()方法来实现初始化各种状态,然后在代码中主动调用好了 V.
在实际的业务开发中,往往不需要我们手写数据结构,而是直接使用标准库的数据结构 / 容器类。...♀️疑问 7: 在带集合的构造方法中,为什么会存在集合转化后的数组类型不是 Object[].class 的情况?...在 《阿里巴巴 Java 开发手册》中,有关于 ArrayList#subList API 的规定。为什么阿里巴巴要做这样的限制呢?...♀️疑问 7:在带集合的构造方法中,为什么会存在集合转化后的数组类型不是 Object[].class 的情况?...而在 ArrayList#toArray() 方法中,返回值的类型是 Object[] 类型,有类型错误风险。
head就是真 throw nullPointer();//这里使用了抛出异常信号的方式,而且抛出的是一个匿名对象(因为要的是它的类型,没必要给对象命名了) //如果采用直接返回的方式...本质是终止函数运行并返回NULL 其他注意事项在代码注释以及code日记中体现 顺序表实现方法 ==注意:这个是带哨兵位的头结点的顺序表!!...教材不好 seqList.h #include using namespace std; //专门作为异常信息的类(用于异常处理抛出); class outofsize { };...{ assert(elem);//感觉判空的时候不如直接用assert,因为为了判空就用异常处理有些大材小用,而且只在判空的时候用assert,这样就直到程序一中断就说明是空指针 //所以关于指针可能为空的情况...,除了完全销毁顺序表之外,还可以清空顺序表(clear函数): 顺序表的头结点也是动态开辟的,但是可以不销毁它,保留下来,这样这个头还在,其他的空间被销毁了,就使得原来的顺序表被清空,再次写入数据的话不用再初始化顺序表
领取专属 10元无门槛券
手把手带您无忧上云