-transient关键字
通常一个类实现序列化方式是实现序列化接口 Serializable
序列化的作用:把数据长久的保存在磁盘中,磁盘和内存是不同的,内存一般在程序运行时占用,数据保存周期短,随程序结束而结束,磁盘可以长久保存数据。
transient关键字的作用,在已实现序列化的类中,有的变量不需要保存在磁盘中,就要transient关键字修饰,如银行卡密码等,就这个作用------在已序列化的类中使变量不序列化。
-整型的运算时要注意的一些规则
char、byte、short相加时会自动转换为int类型:在进行四则运算的时候回自动转化为int类型的值,高精度向低精度会丢失精度。所以 a=a+b; 会报错。但是 a+=b; 会自动强制转化为byte 类型。
--java中的包
java.awt: 包含构成抽象窗口工具集的多个类,用来构建和管理应用程序的图形用户界面
java.lang:
提供java编成语言的程序设计的基础类
java.io: 包含提供多种输出输入功能的类,
java.net: 包含执行与网络有关的类,如URL,SCOKET,SEVERSOCKET,
java.applet: 包含java小应用程序的类
java.util: 包含一些实用性的类。
--Object中的方法
--类加载
java中类的加载有5个过程,加载、验证、准备、解析、初始化;这便是类加载的5个过程,而类加载器的任务是根据一个类的全限定名来读取此类的二进制字节流到JVM中,然后转换为一个与目标类对应的java.lang.Class对象实例,在虚拟机提供了3种类加载器,引导(Bootstrap)类加载器、扩展(Extension)类加载器、系统(System)类加载器(也称应用类加载器);
一个类,由不同的类加载器实例加载的话,会在方法区产生两个不同的类,彼此不可见,并且在堆中生成不同Class实例。装载一个不存在的类的时候,因为采用的双亲加载模式,所以强制加载会直接报错。
双亲委派模式是在Java 1.2后引入的,其工作原理的是,如果一个类加载器收到了类加载请求,它并不会自己先去加载,而是把这个请求委托给父类的加载器去执行,如果父类加载器还存在其父类加载器,则进一步向上委托,依次递归,请求最终将到达顶层的启动类加载器,如果父类加载器可以完成类加载任务,就成功返回,倘若父类加载器无法完成此加载任务,子加载器才会尝试自己去加载,这就是双亲委派模式,即每个儿子都很懒,每次有活就丢给父亲去干,直到父亲说这件事我也干不了时,儿子自己想办法去完成,所以默认是父装载。
--进程
子进程得到的是除了代码段是与父进程共享以外,其他所有的都是得到父进程的一个副本,子进程的所有资源都继承父进程,得到父进程资源的副本,子进程可获得父进程的所有堆和栈的数据,但二者并不共享地址空间。两个是单独的进程,继承了以后二者就没有什么关联了,子进程单独运行;进程的线程之间共享由进程获得的资源,但线程拥有属于自己的一小部分资源,就是栈空间,保存其运行状态和局部自动变量的。
线程之间共享进程获得的数据资源,所以开销小,但不利于资源的管理和保护;而进程执行开销大,但是能够很好的进行资源管理和保护。
线程的通信速度更快,切换更快,因为他们共享同一进程的地址空间。
一个进程可以有多个线程,线程是进程的一个实体,是CPU调度的基本单位。
--单例的线程安全问题
Map家族的继承实现关系如下,注意一点就是顶层的Map接口与Collection接口是依赖关系:
关于Key和Value能否为null的问题:
--基本数据类型的范围和其默认值
默认值 | 存储需求(字节) | 取值范围 | 示例 | |
byte | 0 | 1 | -2^7—2^7-1 | byte b=10; |
char | ‘ \u0000′ | 2 | 0—2^16-1 | char c=’c’ ; |
short | 0 | 2 | -2^15—2^15-1 | short s=10; |
int | 0 | 4 | -2^31—2^31-1 | int i=10; |
long | 0 | 8 | -2^63—2^63-1 | long o=10L; |
float | 0.0f | 4 | -2^31—2^31-1 | float f=10.0F |
double | 0.0d | 8 | -2^63—2^63-1 | double d=10.0; |
boolean | false | 1 | true\false | boolean flag=true; |
--四个修饰符的访问权限
包权限=default权限
--javac中的参数用途:
synchronized关键字和volatile关键字比较:
- volatile关键字是线程同步的轻量级实现,所以volatile性能肯定比synchronized关键字要好。但是volatile关键字只能用于变量而synchronized关键字可以修饰方法以及代码块。synchronized关键字在JavaSE1.6之后进行了主要包括为了减少获得锁和释放锁带来的性能消耗而引入的偏向锁和轻量级锁以及其它各种优化之后执行效率有了显著提升,实际开发中使用 synchronized 关键字的场景还是更多一些。
- 多线程访问volatile关键字不会发生阻塞,而synchronized关键字可能会发生阻塞
- volatile关键字能保证数据的可见性,但不能保证数据的原子性。synchronized关键字两者都能保证。
- volatile关键字主要用于解决变量在多个线程之间的可见性,而 synchronized关键字解决的是多个线程之间访问资源的同步性
总结:synchronized: 具有原子性,有序性和可见性;(三个都有)
volatile:具有有序性和可见性(缺一个原子性)
--ThreadLocal
ThreadLocal类用来提供线程内部的局部变量。这种变量在多线程环境下访问(通过get或set方法访问)时能保证各个线程里的变量相对独立于其他线程内的变量。ThreadLocal实例通常来说都是private static类型的,用于关联线程和线程的上下文。 可以总结为一句话:ThreadLocal的作用是提供线程内的局部变量,这种变量在线程的生命周期内起作用,减少同一个线程内多个函数或者组件之间一些公共变量的传递的复杂度。 举个例子,我出门需要先坐公交再做地铁,这里的坐公交和坐地铁就好比是同一个线程内的两个函数,我就是一个线程,我要完成这两个函数都需要同一个东西:公交卡(北京公交和地铁都使用公交卡),那么我为了不向这两个函数都传递公交卡这个变量(相当于不是一直带着公交卡上路),我可以这么做:将公交卡事先交给一个机构,当我需要刷卡的时候再向这个机构要公交卡(当然每次拿的都是同一张公交卡)。这样就能达到只要是我(同一个线程)需要公交卡,何时何地都能向这个机构要的目的。 有人要说了:你可以将公交卡设置为全局变量啊,这样不是也能何时何地都能取公交卡吗?但是如果有很多个人(很多个线程)呢?大家可不能都使用同一张公交卡吧(我们假设公交卡是实名认证的),这样不就乱套了嘛。现在明白了吧?这就是ThreadLocal设计的初衷:提供线程内部的局部变量,在本线程内随时随地可取,隔离其他线程。
--final
final定义的成员变量可以在代码块(类变量则静态代码块,实例变量普通代码块)里初始化,也可以在构造器中初始化,也可以在声明变量时初始化。final的局部变量声明时不必马上初始化,但使用时必须初始化,而且只能一次赋值。
--jdbc
Class.forName("com.mysql.jdbc.Driver"); //加载jdbc驱动
con=DriverManager.getConnection(url,user,password); //建立连接
stmt=con.createStatement(); //创建语句执行者(stateMent用于执行不带参数的简单sql语句,PreparedStatement用于执行带参数的预编译sql语句能够预防sql注入,CallableStatement提供了一种标准形式的调用存储过程的方法)
stmt.execute(“sql语句”);
rs=stmt.executeQuery("sql查询语句"); //结果集
--list,set,map三者的关系
--JVM的命令
1、jps:查看本机java进程信息。
2、jstack:打印线程的栈信息,制作线程dump文件。
3、jmap:打印内存映射,制作堆dump文件
4、jstat:性能监控工具
5、jhat:内存分析工具
6、jconsole:简易的可视化控制台
7、jvisualvm:功能强大的控制台
javac.exe是编译.java文件
java,exe执行编译好的.class文件
javadoc.exe用来制作java文档
jdb.exe是java的调试器
javaprof,exe是剖析工具
--如果希望监听TCP端口9000,服务器端应该怎样创建socket?
new Socket("localhost",9000); ---x 这个是客户端的语句
new ServerSocket(9000);-------√
new Socket(9000);-----x
new ServerSocket("localhost",9000);-----x
---抽象类
特点:
1.抽象类中可以构造方法
2.抽象类中可以存在普通属性,方法,静态属性和方法。
3.抽象类中可以存在抽象方法。
4.如果一个类中有一个抽象方法,那么当前类一定是抽象类;抽象类中不一定有抽象方法。
5.抽象类中的抽象方法,需要有子类实现,如果子类不实现,则子类也需要定义为抽象的。
---接口
1.在接口中只有方法的声明,没有方法体。
2.在接口中只有常量,因为定义的变量,在编译的时候都会默认加上
public static final
3.在接口中的方法,永远都被public来修饰。
4.接口中没有构造方法,也不能实例化接口的对象。
5.接口可以实现多继承
6.接口中定义的方法都需要有实现类来实现,如果实现类不能实现接口中的所有方法则实现类定义为抽象类。
--使用泛型的好处
1,类型安全。 泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。
2,消除强制类型转换。 泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。
3,潜在的性能收益。 泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。
总结:所以泛型只是提高了数据传输安全性,并没有改变程序运行的性能
--最长无重复子数组
就是无重复的连续数组的最大长度是多少
public static void main(String[] args) {
// 最长无重复子数组
int arr[]= {2,3,3,4,5,6,4};
HashMap<Integer, Integer> map = new HashMap<>();//利用map集合中不可重复值的特性
int max = 0;
for (int i = 0, j = 0; i < arr.length; ++i) {
if (map.containsKey(arr[i])) {
/**
* 因为i移动到了有相同值的位置 所以要移动j到i的位置 然后i再向前移动
* 之后再用i-j+1就可以得到两个之间的长度
*/
j = Math.max(j, map.get(arr[i])+1); //2 3 3
//map.get(arr[i])这个值就是找到相同值的上一个值,加一j就可以到i的位置
}
map.put(arr[i], i); //(2,0)(3,1)(3,2);
max = Math.max(max, i - j + 1);
}
System.out.println(max);
}
}
--合并两个有序的数组
给出一个整数数组 和有序的整数数组 ,请将数组 合并到数组 中,变成一个有序的升序数组
注意:
1.可以假设 数组有足够的空间存放 数组的元素, 和 中初始的元素数目分别为 和 , 的数组空间大小为 m+n
2.不要返回合并的数组,返回是空的,将数组 的数据合并到 里面就好了
3.数组在[0,m-1]的范围也是有序的
例1:
A: [4,5,6,0,0,0],m=3
B: [1,2,3],n=3
合并过后A为:
A: [1,2,3,4,5,6]
public void merge(int A[], int m, int B[], int n) {
for(int i=m;i<m+n;i++){
A[i]=B[i-m];
}
Arrays.sort(A);
}
--重写
两同两小一大原则,即: 方法名相同,参数类型相同。 子类返回类型小于等于父类方法返回类型。 子类抛出异常小于等于父类方法抛出异常。 子类访问权限大于等于父类方法访问权限。
--replaceAll方法
replaceAll方法的第一个参数是一个正则表达式,而"."在正则表达式中表示任何字符,所以会把前面字符串的所有字符都替换成"/"。如果想替换的只是".",那么久要写成"\\."
--取模运算,余数的符号跟被除数符号相同
--下面有关SPRING的事务传播特性
Spring的API设计很不错,基本上根据英文翻译就能知道作用:Required:必须的。说明必须要有事物,没有就新建事物。supports:支持。说明仅仅是支持事务,没有事务就非事务方式执行。mandatory:强制的。说明一定要有事务,没有事务就抛出异常。required_new:必须新建事物。如果当前存在事物就挂起。not_supported:不支持事物,如果存在事物就挂起。never:绝不有事务。如果存在事物就抛出异常
事务属性的种类: 传播行为、隔离级别、只读和事务超时
传播行为 | 意义 |
PROPERGATION_MANDATORY | 表示方法必须运行在一个事务中,如果当前事务不存在,就抛出异常 |
PROPAGATION_NESTED | 表示如果当前事务存在,则方法应该运行在一个嵌套事务中。否则,它看起来和 PROPAGATION_REQUIRED 看起来没什么俩样 |
PROPAGATION_NEVER | 表示方法不能运行在一个事务中,否则抛出异常 |
PROPAGATION_NOT_SUPPORTED | 表示方法不能运行在一个事务中,如果当前存在一个事务,则该方法将被挂起 |
PROPAGATION_REQUIRED | 表示当前方法必须运行在一个事务中,如果当前存在一个事务,那么该方法运行在这个事务中,否则,将创建一个新的事务 |
PROPAGATION_REQUIRES_NEW | 表示当前方法必须运行在自己的事务中,如果当前存在一个事务,那么这个事务将在该方法运行期间被挂起 |
PROPAGATION_SUPPORTS | 表示当前方法不需要运行在一个是事务中,但如果有一个事务已经存在,该方法也可以运行在这个事务中 |
隔离级别
在操作数据时可能带来 3 个副作用,分别是脏读、不可重复读、幻读。为了避免这 3 中副作用的发生,在标准的 SQL 语句中定义了 4 种隔离级别,分别是未提交读、已提交读、可重复读、可序列化。而在 spring 事务中提供了 5 种隔离级别来对应在 SQL 中定义的 4 种隔离级别,如下:
隔离级别 | 意义 |
ISOLATION_DEFAULT | 使用后端数据库默认的隔离级别 |
ISOLATION_READ_UNCOMMITTED | 允许读取未提交的数据(对应未提交读),可能导致脏读、不可重复读、幻读 |
ISOLATION_READ_COMMITTED | 允许在一个事务中读取另一个已经提交的事务中的数据(对应已提交读)。可以避免脏读,但是无法避免不可重复读和幻读 |
ISOLATION_REPEATABLE_READ | 一个事务不可能更新由另一个事务修改但尚未提交(回滚)的数据(对应可重复读)。可以避免脏读和不可重复读,但无法避免幻读 |
ISOLATION_SERIALIZABLE | 这种隔离级别是所有的事务都在一个执行队列中,依次顺序执行,而不是并行(对应可序列化)。可以避免脏读、不可重复读、幻读。但是这种隔离级别效率很低,因此,除非必须,否则不建议使用。 |
---解决哈希冲突
threadlocal 使用开放地址法 - 线性探测法:当前哈希槽有其他对象占了,顺着数组索引寻找下一个,直到找到为止
hashset 中调用 hashmap 来存储数据的,hashmap 采用的链地址法:当哈希槽中有其他对象了,使用链表的方式连接到那个对象上
--JAVA常用的节点流:
- 文 件 FileInputStream FileOutputStrean FileReader FileWriter 文件进行处理的节点流。
- 字符串 StringReader StringWriter 对字符串进行处理的节点流。
- 数 组 ByteArrayInputStream ByteArrayOutputStreamCharArrayReader CharArrayWriter 对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
- 管 道 PipedInputStream PipedOutputStream PipedReaderPipedWriter对管道进行处理的节点流。
--常用处理流(关闭处理流使用关闭里面的节点流)
- 缓冲流:BufferedInputStrean BufferedOutputStream BufferedReader BufferedWriter 增加缓冲功能,避免频繁读写硬盘。
- 转换流:InputStreamReader OutputStreamReader 实现字节流和字符流之间的转换。
- 数据流 DataInputStream DataOutputStream 等-提供将基础数据类型写入到文件中,或者读取出来.
--链接:下列代码片段中,存在编辑错误的语句是()__牛客网
来源:牛客网
做这一题需要知道两个知识点:
byte b1=1,b2=2,b3,b6,b8;
final byte b4=4,b5=6,b7;
b3=(b1+b2); -
- - - -错误 会变成两个int运算
b6=b4+b5; -
- - - -正确 final修饰不会自动提升
b8=(b1+b4); - - - - - 错误
虽然b4不会提升,但b1会提升,所以要强转
b7=(b2+b5); - - - - - 同上
1.所有的byte,short,char类型的值在原酸的时候会被提升为int类型
2.被final修饰的变量不会自动的改变类型,当两个final修饰的变量操作时,结果会根据左边变量的类型而转换
---下列哪些操作会使线程释放锁资源
1.sleep会使当前线程睡眠指定时间,不释放锁
2.yield会使当前线程重回到可执行状态,等待cpu的调度,不释放锁
3.wait会使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll唤醒时进入可执行状态
4.当前线程调用 某线程.join()时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁。
---关系模式的英文表示
is-a 表示继承:Gadget is-a Widget就表示Gadget 继承 Widget;
has-a 表示从属:Gadget has-a Sprocket就表示Gadget中有Sprocket的引用,Sprocket是Gadget的组成部分;
like-a 表示组合:如果A like-a B,那么B就是A的接口
use-a 表示依赖
Servlet生命周期分成3个阶段:
1)初始化阶段:调用init方法
2)响应客户请求:调用service
3)终止:调用destroy方法
Servlet它是作为来自 Web 浏览器或其他 HTTP 客户端的请求和 HTTP 服务器上的数据库或应用程序之间的中间层。
JEE5.0中的Servlet相关的就下面这几个包: javax.servlet javax.servlet.jsp java.servlet.jsp.el java.servlet.jsp.tagext 而最用得多的就是 javax.servlet javax.servlet.http 这两个包了.
请问所有的异常类皆直接继承于哪一个类?()
-
java.applet.Applet
-
java.lang.Throwable
-
java.lang.Exception
-
java.lang.Error
正确答案:C 注意:这里是指异常类的直接继承 所有是Exception Throwable是总基类
--下列叙述中,错误的是( )
正确答案: B 你的答案: B (正确)
File类能够存储文件属性
File类能够读写文件
File类能够建立文件
File类能够获取文件目录信息
题解:
File类能操作文件本身,但不能对文件内容进行修改
能够读写文件的是数据流(OutputStream和InputStream)
--事务
原子性:事务是一组不可分割的操作单元,这组单元要么同时成功要么同时失败(由DBMS的事务管理子系统来实现); 一致性:事务前后的数据完整性要保持一致(由DBMS的完整性子系统执行测试任务); 隔离性:多个用户的事务之间不要相互影响,要相互隔离(由DBMS的并发控制子系统实现); 持久性:一个事务一旦提交,那么它对数据库产生的影响就是永久的不可逆的,如果后面再回滚或者出异常,都不会影响已提交的事务(由DBMS的恢复管理子系统实现的)
--JDK中提供了三个ClassLoader,根据层级从高到低为:
- Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
- Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
- Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器
--方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是gc释放 Java 的垃圾回收器(GC)主要针对堆区,所以在栈区中的方法调用就不会由GC释放。
--Socket 通信编程
客户端通过new Socket()方法创建通信的Socket对象
服务器端通过new ServerSocket()创建TCP连接对象 accept接纳客户端请求
--web容器
Apache就是一个Http服务器,Tomcat是一个web容器,静态的htmlApache还可以处理,但是动态的需要转发给Tomcat去处理了,比如jsp页面,请求先经由Apache转发给Tomcat再由Tomcat解析请求。所以应该是web容器去解析成request对象。
--Java内存区域
程序计数器是一块较小的内存空间,它的作用可以看做是当前线程所执行的字节码的信号指示器(偏移地址),Java编译过程中产生的字节码有点类似编译原理的指令,程序计数器的内存空间存储的是当前执行的字节码的偏移地址,每一个线程都有一个独立的程序计数器(程序计数器的内存空间是线程私有的),因为当执行语句时,改变的是程序计数器的内存空间,因此它不会发生内存溢出 ,并且程序计数器是jvm虚拟机规范中唯一一个没有规定 OutOfMemoryError 异常 的区域;
.java虚拟机栈:线程私有,生命周期和线程一致。描述的是 Java 方法执行的内存模型:每个方法在执行时都会床创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法从调用直至执行结束,就对应着一个栈帧从虚拟机栈中入栈到出栈的过程。 没有类信息,类信息是在方法区中
java堆:对于绝大多数应用来说,这块区域是 JVM 所管理的内存中最大的一块。线程共享,主要是存放对象实例和数组
方法区:属于共享内存区域,存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
1、基本型和基本型封装型进行“==”运算符的比较,基本型封装型将会自动拆箱变为基本型后再进行比较,因此Integer(0)会自动拆箱为int类型再进行比较,显然返回true;
int a = 220;
Integer b = 220;
System.out.println(a==b);//true
2、两个Integer类型进行“==”比较, 如果其值在-128至127 ,那么返回true,否则返回false, 这跟Integer.valueOf()的缓冲对象有关,这里不进行赘述。
Integer c=3;
Integer h=3;
Integer e=321;
Integer f=321;
System.out.println(c==h);//true
System.out.println(e==f);//false
3、两个基本型的封装型进行equals()比较,首先equals()会比较类型,如果类型相同,则继续比较值,如果值也相同,返回true。
Integer a=1;
Integer b=2;
Integer c=3;
System.out.println(c.equals(a+b));//true
4、基本型封装类型调用equals(),但是参数是基本类型,这时候,先会进行自动装箱,基本型转换为其封装类型,再进行3中的比较。
int i=1;
int j = 2;
Integer c=3;
System.out.println(c.equals(i+j));//true
总结:包装类的“==”运算在不遇到算术运算的情况下不会自动拆箱
包装类的equals()方法不处理数据转型
公式-n=~n+1可推出~n=-n-1
--编码为UTF8 char:
char值为英文字符所占字节长度:1
char值为中文字符所占字节长度:3
编码为GBK(默认编码):
char值为英文字符所占字节长度:2
char值为中文字符所占字节长度:2
-------------------------------
--编码为UTF8 String:
String为英文字母所占字节长度:1
String为中文字母所占字节长度:3
编码为GBK:
String为英文字母所占字节长度:1
String为中文字母所占字节长度:2
String为英文字母(全角)所占字节长度:2
在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:成员内部类,局部内部类,匿名内部类,静态内部类 。
1.成员内部类
(1)该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员);
(2)成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量 或 外部类.this.成员方法】;
(3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;
(4)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象;
(5)内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。如果成员内部类用private修饰,则只能在外部类的内部访问;如果用public修饰,则任何地方都能访问;如果用protected修饰,则只能在同一个包下或者继承外部类的情况下访问;如果是默认访问权限,则只能在同一个包下访问。外部类只能被public和包访问两种权限修饰。
2.局部内部类
(1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;
(2)局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
3.匿名内部类
(1)一般使用匿名内部类的方法来编写事件监听代码;
(2)匿名内部类是不能有访问修饰符和static修饰符的;
(3)匿名内部类是唯一一种没有构造器的类;
(4)匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
4.内部静态类
(1)静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似;
(2)不能使用外部类的非static成员变量或者方法。
子父类各类正确的执行顺序是:
父类B静态代码块->子类A静态代码块->
父类B非静态代码块->父类B构造函数->
子类A非静态代码块->子类A构造函数
在Java中,对于不再使用的内存资源,如调用完成的方法,“垃圾回收器”会自动将其释放。--错
JVM 内存可简单分为三个区:
1、堆区(heap):用于存放所有对象,是线程共享的(注:数组也属于对象)
2、栈区(stack):用于存放基本数据类型的数据和对象的引用,是线程私有的(分为:虚拟机栈和本地方法栈)
3、方法区(method):用于存放类信息、常量、静态变量、编译后的字节码等,是线程共享的(也被称为非堆,即 None-Heap)
Java 的垃圾回收器(GC)主要针对堆区。方法调用时,会创建栈帧在栈中,调用完是程序自动出栈释放,而不是gc释放
--servlet
抛InterruptedException的代表方法有:
-
java.lang.Object 类的 wait 方法
-
java.lang.Thread 类的 sleep 方法
-
java.lang.Thread 类的 join 方法