1.Java枚举的内部实现:
枚举类在后台实现时,实际上是转化为一个继承了java.lang.Enum类的实体类,原先的枚举类型变成对应的实体类型,上例中AccountType变成了个class AccountType,并且会生成一个新的构造函数,若原来有构造函数,则在此基础上添加两个参数,生成新的构造函数,如上例子中:
实例枚举源码:
enum AccountType
{
SAVING, FIXED, CURRENT;
private AccountType()
{
System.out.println(“It is a account type”);
}
}
class EnumOne
{
public static void main(String[]args)
{
System.out.println(AccountType.FIXED);
}
}
1
|
private
AccountType(){ System.out.println(“It is a account type”); }
|
会变成:
1
2
|
private
AccountType(String s,
int
i){
super
(s,i); System.out.println(“It is a account type”); }
|
1
2
3
|
public
static
final
AccountType SAVING;
public
static
final
AccountType FIXED;
public
static
final
AccountType CURRENT;
|
而且还会添加一段static代码段:
1
2
3
4
5
6
|
static
{
SAVING =
new
AccountType(
"SAVING"
,
0
);
... CURRENT =
new
AccountType(
"CURRENT"
,
0
);
$VALUES =
new
AccountType[]{
SAVING, FIXED, CURRENT
} }
|
2.HttpServlet容器响应Web客户请求流程
- 1)Web客户向Servlet容器发出Http请求;
- 2)Servlet容器解析Web客户的Http请求;
- 3)Servlet容器创建一个HttpRequest对象,在这个对象中封装Http请求信息;
- 4)Servlet容器创建一个HttpResponse对象;
- 5)Servlet容器调用HttpServlet的service方法,这个方法中会根据request的Method来判断具体是执行doGet还是doPost,把 HttpRequest和HttpResponse对象作为service方法的参数传给HttpServlet对象;
- 6)HttpServlet调用HttpRequest的有关方法,获取HTTP请求信息;
- 7)HttpServlet调用HttpResponse的有关方法,生成响应数据;
- 8)Servlet容器把HttpServlet的响应结果传给Web客户。
doGet() 或 doPost() 是创建HttpServlet时需要覆盖的方法.
3.中间件
中间件是一种独立的系统软件或服务程序,分布式应用软件借助这种软件在不同的技术之间共享资源。中间件位于客户机/ 服务器的操作系统之上,管理计算机资源和网络通讯。是连接两个独立应用程序或独立系统的软件。相连接的系统,即使它们具有不同的接口,但通过中间件相互之间仍能交换信息。执行中间件的一个关键途径是信息传递。通过中间件,应用程序可以工作于多平台或OS环境。
(简单来说,中间件并不能提高内核的效率,一般只是负责网络信息的分发处理)
中间件特点的描述:
1. 中间件应支持标准的协议和接口
2. 中间件可运行于多种硬件和操作系统平台上
3. 跨越网络,硬件,操作系统平台的应用或服务可通过中间件透明交互
4.Integer需要注意的点
代码片段
1
2
3
4
5
6
7
8
9
10
11
12
|
public
class
Test03 {
public
static
void
main(String[] args) {
Integer f1 =
100
, f2 =
100
, f3 =
150
, f4 =
150
;
System. out.println( f1 == f2);
//true
System. out.println( f3 == f4);
//false
}
}
|
当我们给一个Integer赋予一个int类型的时候会调用Integer的静态方法valueOf。
Integer f1 = Integer.valueOf(100);
Integer f2 = Integer.valueOf(100);
Integer f3 = Integer.valueOf(150);
Integer f4 = Integer.valueOf(150);
思考:那么Integer.valueOf()返回的Integer是不是是重新new Integer(num);来创建的呢?如果是这样的话,那么== 比较返回都是false,因为他们引用的堆地址不一样。
具体来看看Integer.valueOf的源码
1
2
3
4
5
6
|
public
static
Integer valueOf(
int
i) {
if
(i >= IntegerCache.low && i <= IntegerCache.high)
return
IntegerCache.cache[i + (-IntegerCache.low)];
return
new
Integer(i);
}
|
在IntegerCache中cache数组初始化如下,存入了-128 - 127的值
1
2
3
4
5
|
cache =
new
Integer[(high - low) +
1
];
int
j = low;
for
(
int
k =
0
; k < cache.length ; k ++)
cache[k] =
cache[k] =
new
Integer(j ++);
|
从上面我们可以知道给Interger 赋予的int数值在-128 - 127的时候,直接从cache中获取,这些cache引用对Integer对象地址是不变的,但是不在这个范围内的数字,则new Integer(i) 这个地址是新的地址,不可能一样的.
5.Java多线程需要注意的点
Java中的多线程是一种抢占式的机制,而不是分时机制。抢占式的机制是有多个线程处于可运行状态,但是只有一个线程在运行。
共同点 :
共同点 :
- 1. 他们都是在多线程的环境下,都可以在程序的调用处阻塞指定的毫秒数,并返回。
- 2. wait()和sleep()都可以通过interrupt()方法 打断线程的暂停状态 ,从而使线程立刻抛出InterruptedException。
- 如果线程A希望立即结束线程B,则可以对线程B对应的Thread实例调用interrupt方法。如果此刻线程B正在wait/sleep/join,则线程B会立刻抛出InterruptedException,在catch() {} 中直接return即可安全地结束线程。
- 需要注意的是,InterruptedException是线程自己从内部抛出的,并不是interrupt()方法抛出的。对某一线程调用 interrupt()时,如果该线程正在执行普通的代码,那么该线程根本就不会抛出InterruptedException。但是,一旦该线程进入到 wait()/sleep()/join()后,就会立刻抛出InterruptedException 。
- 1.每个对象都有一个锁来控制同步访问。Synchronized关键字可以和对象的锁交互,来实现线程的同步。
- sleep方法没有释放锁,而wait方法释放了锁,使得其他线程可以使用同步控制块或者方法。
- 2.wait,notify和notifyAll只能在同步控制方法或者同步控制块里面使用,而sleep可以在任何地方使用
- 3.sleep必须捕获异常,而wait,notify和notifyAll不需要捕获异常
- 4.sleep是线程类(Thread)的方法,导致此线程暂停执行指定时间,给执行机会给其他线程,但是监控状态依然保持,到时后会自动恢复。调用sleep不会释放对象锁。
- 5.wait是Object类的方法,对此对象调用wait方法导致本线程放弃对象锁,进入等待此对象的等待锁定池,只有针对此对象发出notify方法(或notifyAll)后本线程才进入对象锁定池准备获得对象锁进入运行状态。
6.abstract、static、final
关键字abstract:
- 抽象方法只能定义在抽象类中;
- 抽象方法和抽象类必须由abstract修饰;
- abstract关键字只能描述类和方法,不能描述变量;
- 抽象方法只定义方法声明,不定义方法实现;
- 抽象类不可以被实例化(创建对象),只有通过子类继承抽象类并覆盖抽象类中的所有抽象方法后,该子类才可以被实例化,否则该子类还是一个抽象类。
- 抽象类中有构造函数用于给子类对象进行初始化,同时抽象类中可以含有非抽象方法;
- abstract关键字不可以与final,private,static关键字共存,因为被final修饰的方法不可以被重写,意味着子类不可以重写该方法,如果abstract和final共同修饰父类中的方法,子类要实现抽象方法(abstract的作用),而final又不让该方法重写,这相互矛盾。如果private和abstract共同修饰父类中的方法,private修饰则该方法不可以被子类访问,但是abstract修饰需要子类去实现,两者产生矛盾。如果static和abstract共同修饰父类中的方法,static表示是静态的方法,随着类的加载而加载,则该方法不需要在子类中去实现,这与abstract关键字矛盾。
static关键字:
- static用于修饰成员变量和成员函数,想要实现对象中的共性数据的对象共享,可以将这个数据进行静态修饰,被静态修饰的成员可以直接被类名调用,静态随着类的加载而加载,而且优先于对象存在。
- 静态方法只能访问静态成员(静态方法和静态变量),不可以访问非静态成员,这是因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员。
- 静态方法中不能使用this和super关键字,因为this代表本类对象,super代表父类对象,而静态时,有可能没有对象存在,所以this和super无法使用。
final关键字:
- final关键字可以修饰类,方法,变量(成员变量内,局部变量,静态变量)。
- 被final修饰的类是一个最终类,不可以被继承,被final修饰的方法是一个最终方法,不可以被覆盖,但是可以被继承。
- 被final修饰的变量只能是一个常量,只能赋值一次。
- 内部类被定义在类中的局部位置上时,只能访问局部被final修饰的局部变量。
补充:
- 成员变量有初始值,局部变量没有初始值。
- 创建String时,会在字符串常量池中寻找,当找到需要的hello时,不进行字符串的创建,引用已有的。 所以,String s = "hello";String t = "hello";s==t返回true,s.equals(t)也是true。
- getParameter()是获取POST/GET传递的参数值;
- getInitParameter获取Tomcat的server.xml中设置Context的初始化参数
- getAttribute()是获取对象容器中的数据值;
- getRequestDispatcher是请求转发
- java,exe是java虚拟机
- javadoc.exe用来制作java文档
- jdb.exe是java的调试器
- javaprof,exe是剖析工具
- java8中允许接口有默认方法和类方法