反射
# Class的三种获取方式
# 方式一:通过Class.forName获取
Class cla1 = Class.forName("<类名>");
# 方式二:通过类属性 <类名>.class获取
Class cla2 = <类名>.class;
# 方式三:通过对象方法 <对象>.getClass()
Class cla3 = <对象>.getClass();
可变变量
到J2SE 1.4为止,一直无法在Java程序里定义实参个数可变的方法——因为Java要求实参(Arguments)和形参(Parameters)的数量和类型都必须逐一匹配,而形参的数目是在定义方法时就已经固定下来了。尽管可以通过重载机制,为同一个方法提供带有不同数量的形参的版本,但是这仍然不能达到让实参数量任意变化的目的。然而,有些方法的语义要求它们必须能接受个数可变的实参——例如著名的main方法,就需要能接受所有的命令行参数为实参,而命令行参数的数目,事先根本无法确定下来。对于这个问题,传统上一般是采用“利用一个数组来包裹要传递的实参”的做法来应付。
1. 用数组包裹实参
“用数组包裹实参”的做法可以分成三步:首先,为这个方法定义一个数组型的参数;然后在调用时,生成一个包含了所有要传递的实参的数组;最后,把这个数组作为一个实参传递过去。这种做法可以有效的达到“让方法可以接受个数可变的参数”的目的,只是调用时的形式不够简单。J2SE 1.5中提供了Varargs机制,允许直接定义能和多个实参相匹配的形参。从而,可以用一种更简单的方式,来传递个数可变的实参。
Varargs的含义
大体说来,“Varargs”是“variable number of arguments”的意思。有时候也被简单的称为“variable arguments”,不过因为这一种叫法没有说明是什么东西可变,所以意义稍微有点模糊。
2. 定义实参个数可变的方法
只要在一个形参的“类型”与“参数名”之间加上三个连续的“.”(即“...”,英文里的句中省略号),就可以让它和不确定个实参相匹配。而一个带有这样的形参的方法,就是一个实参个数可变的方法。
清单1:一个实参个数可变的方法
private static int sumUp(int... values) {
}
注意,只有最后一个形参才能被定义成“能和不确定个实参相匹配”的。因此,一个方法里只能有一个这样的形参。另外,如果这个方法还有其它的形参,要把它们放到前面的位置上。编译器会在背地里把这最后一个形参转化为一个数组形参,并在编译出的class文件里作上一个记号,表明这是个实参个数可变的方法。
清单2:实参个数可变的方法的秘密形态
private static int sumUp(int[] values) {
}
由于存在着这样的转化,所以不能再为这个类定义一个和转化后的方法签名一致的方法。
清单3:会导致编译错误的组合
private static int sumUp(int... values) {
}
private static int sumUp(int[] values) {
}
3. 调用实参个数可变的方法
只要把要传递的实参逐一写到相应的位置上,就可以调用一个实参个数可变的方法。不需要其它的步骤。
清单4:可以传递若干个实参
sumUp(1, 3, 5, 7);
在背地里,编译器会把这种调用过程转化为用“数组包裹实参”的形式:
清单5:偷偷出现的数组创建
sumUp(new int[]{1, 2, 3, 4});
另外,这里说的“不确定个”也包括零个,所以这样的调用也是合乎情理的:
清单6:也可以传递零个实参
sumUp();
这种调用方法被编译器秘密转化之后的效果,则等同于这样:
清单7:零实参对应空数组
sumUp(new int[]{});
注意这时传递过去的是一个空数组,而不是null。这样就可以采取统一的形式来处理,而不必检测到底属于哪种情况。
线程池技术
Tomcat调优
1.内存调优:修改bin/catalina.sh文件中的JAVA_OPTS参数,主要是–Xms和-Xmx的值
2.线程池调优:conf/server.xml
当内存不足时,系统会触发垃圾回收机制(GC),可能也会导致CPU过载。因此当CPU过高时,应考虑是否由内存引起的。
Tomcat问题排查
1.开启startup.bat后一闪而过,末尾加pause打印log显示没有设置JAVA_HOME和JRE_HOME环境变量。
解决方案:必须设置JAVA_HOME和JRE_HOME。若设置后启动仍然提示设置环境变量,则直接在startup.bat开头加入
set JAVA_HOME=C:\Program Files\Java\jdk1.8.0_181
set JRE_HOME=C:\Program Files\Java\jre1.8.0_181
2.启动后控制台显示的log有中文乱码。
解决方案:在conf/logging.properties文件中设置java.util.logging.ConsoleHandler.encoding = GBK