一、java理解
1、Java特性:面向对象(封装,继承,多态)、平台无关性(JVM运行.class文件、)、语言(泛型,Lambda)、 类库(集合,并发,网络IO/NIO) 、JRE(Java运行环境,JVM,类库) 、JDK(Java开发工具,包括JRE,javac,诊断工具)。GC机制(Java的内存结构,堆、栈、方法区等,然后围绕什么样的对象可以 回收以及回收的执行)。
2、Java分为编译期和运行时。Javac的编译,编译Java源码生成“.class”文件,而不是可以直接执行的机器码。Java通过字节码和Java虚拟机(JVM)这种跨平台的抽象,屏蔽了操作系统和硬件的细节,这也是实现“一次编译,到处执行”的基础。
3、程序从源代码到运行的三个阶段:编码——编译——运行——调试。首先是将Java源代码转化成.class文件字节码,.class文件就是可以到处运行的文件。然后Java字节码会被转化为目标机器代码,这是是由JVM来执行的。
4、Java源代码经过Javac编译成.class文件.class文件经JVM解析或编译运行。
5、jre为java提供了必要的运行时环境,jdk为java提供了必要的开发环境!
6、写个程序直接执行字节码就是解释执行。写个程序运行时把字节码动态翻译成机器码就是jit。写个程序把源文件直接编译为机器码就是aot。
7、编译程序是整体编译完了,再一次性执行。 而解释程序是一边解释,一边执行 。JAVA语言是一种编译型-解释型语言,同时具备编译特性和解释特性。比如我们大多数情况使用的Hotspot JVM,都提供了动态编译器编译器JIT,能够追踪热点代码, 然后变成机器指令,这种情况下部分热点代码就属于编译执行,而不是解释执行了。
二、异常处理
1、Exception和Error都是继承了Throwable类,在Java中只有Throwable类型的实例才可以被抛出(throw)或者捕获(catch),它是异常处理机制的基本组成类型。
Exception是程序正常运行中,可以预料的意外情况,可能并且应该被捕获,进行相应处理。Error是指在正常情况下,不大可能出现的情况,不便于也不需要捕获,常见的比如OutOfMemoryError之类,都是Error的子类。
Exception又分为可检查(checked)异常和不检查(unchecked)异常,可检查异常在源代码里必须显式地进行捕获处理,这是编译期检查的一部分。
不检查异常就是所谓的运行时异常,类似 NullPointerException、ArrayIndexOutOfBoundsException之类,通常是可以编码避免的逻辑错误,具体根据需要来判断是否需要捕 获,并不会在编译期强制要求。
2、try-catch代码段会产生额外的性能开销,或者换个角度说,它往往会影响JVM对代码进行优化,所以建议仅捕获有必要的代码段,尽量不要一个大的try包住整段的代码;与此同时,利用异常控制代码流程,也不是一个好主意,远比我们通常意义上的条件语句(if/else、switch)要低效。
3、不要在fnally代码块中处理返回值。会出现了先返回,再执行finally,再重置返回值的情况。如try抛出异常finally正确·返回,异常就会被屏蔽。即使try中break和coninue,也可能使控制权进入finally中。
4、 请勿在try代码块中调用return、break或continue语句。万一无法避免,一定要确保fnally的存在不会改变函数的返回值。 函数返回值有两种类型:值类型与对象引用。对于对象引用,要特别小心,如果在fnally代码块中对函数返回的对象成员属性进行了修改,即使不在fnally块中显式调用return语句,这个修改也会作用于返回值上。
5、.当一个try后跟了很多个catch时,必须先捕获小的异常再捕获大的异常。try中的代码块不宜过长,捕获时不宜大而全,fnally里只释放资源不要有业务逻辑,尤其是修改返回值。
6、throw作用于作用在方法内,抛出具体异常,throws作用在方法声明上,抛出异常实体类。关键字throws运用于方法声明之上,用于表示当前方法不处理异常,而是提醒该方法的调用者来处理异常(抛出异常).
7、如果父类抛出了多个异常,子类重写父类方法时,抛出和父类相同的异常或者是父类异常的子类或者不抛出异 常。 父类方法没有抛出异常,子类重写父类该方法时也不可抛出异常。此时子类产生该异常,只能捕获处理,不 能声明抛出 。
8、 自定义一个编译期异常: 自定义类 并继承于 java.lang.Exception 。 自定义一个运行时期的异常类:自定义类 并继承于 java.lang.RuntimeException 。
6、常见异常
算数异常类:Arithmetic Exception
空指针异常类:NullPotiner Exception
类型强制转换:ClassCast Exception
数组负下标异常:Negative Array Exception
数组下标越界:ArrayIndexOutOfBounds Exception
文件已结束异常:EOPException
文件未找到:FileNotFoundException
字符串转换数字异常:Number Format Exception
输入输出异常:IOException
数据格式异常:NumberFormatException
三、String、StringBufer、StringBuilder
1、String被声明成为fnal类,所有属性也都是fnal的。也由于它的不可变性,类似拼接、裁剪字符串等动作,都会产生新的String对象。
2、StringBufer可以使用其append或者add方法,把字符串添加到已有序列的末尾或者指定位置。StringBufer本质是一个线程安全的可修改字符序列,它保证了线程安全,也随之带来了额外的性能开销。在多线程环境下,建议使用StringBufer,例如XML解析、HTTP参数解析与封装。
3、StringBuilder能力上和StringBufer没有本质区别,但是它去掉了线程安全的部分,有效减小了开销。在单线程环境下,建议使用StringBuilder,例如SQL语句拼装、JSON封装等。
4、在JDK 8中,字符串拼接操作会自动被javac转换为StringBuilder操作,而在JDK 9里面则是因为Java 9为了更加统一字符串操作优化,提供 了StringConcatFactory,作为一个统一的入口。
5、Java为了避免在一个系统中产生大量的String对象,引入了字符串常量池。其运行机制是:创建一个字符串时,首先检查池中是否有值相同的字符串对 象,如果有则不需要创建直接从池中刚查找到的对象引用;如果没有则新建字符串对象,返回对象引用,并且将新创建的对象放入池中。但是,通过new方法创建的String对象是不检查字符串池的,而是直接在堆区或栈区创建一个新的对象,也不会把对象放入池中。
四·、反射和动态代理
1、JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java语言的反射机制。
2、当程序主动使用某个类时,如果该类还未被加载到内存中,则JVM会通过加载、连接、初始化3个步骤来对该类进行初始化。加载指的是将类的class文件读入到内存,并为之创建一个java.lang.Class对象。可以通过继承ClassLoader基类来创建自己的类加载器,或者由JVM提供。JVM预定义有三种类加载器。
根类加载器,加载 Java 的核心类、扩展类加载器(extensions class loader):它负责加载JRE的扩展目录、系统类加载器,被称为系统(也称为应用)类加载器。
3、动态代理
Java提供了一个Proxy类,调用它的newInstance方法可以生成某个对象的代理对象,该方法需要三个参数。
参数一:生成代理对象使用哪个类装类.class.getClassLoader()
参数二:生成哪个对象的代理对象,通过接口指定(代理对象拥有目标对象相同的方法,代理对象会实现接口的所有方法)接口实现.class.getInterfaces()
参数三:生成的代理对象的方法里干什么事 handler(invoke())
静态代理需要自己写代理类,代理类需要实现与目标对象相同的接口,而动态代理不需要自己编写代理类因为·它是动态生成的。