1、static方法不能访问非static方法,因为static方法是属于这个类本身的一个方法,在编译期间就已经确定了;而非static方法是属于这个类的对象的方法,需要在实例化之后才能访问到。若在static方法中访问非static方法,将不能通过编译。也可以通过java编译类的顺序来解释。因为在java编译类的过程中先编译static变量、static方法、所以,在你使用static方法的时候非static方法都没有进行编译,所以不能访问。
2、通过重载方法的参数类型和顺序来进行区分的。注意:若参数类型和顺序均相同时,不管参数名是否相同,编译器均会报错,提示方法已经被定义。且不能根据返回值类型来区分,如果根据返回值来区分的话,有时程序里调用方法时并不需要返回值,那么程序都无法确定该调用那个重载方法。这里需要了解方法重载的定义:我的理解是,方法名相同且方法的参数列表不一样。跟返回值和参数顺序没有关系。
3、在一个构造器中调用其它构造器时,需要使用this关键字进行调用,如this();在一个构造器中可调用仅一个其它构造器,并且调用其它构造器的语句需放在调用者(即发出调用行为的构造器)语句块的第一行。
4、static关键字为何不能修饰局部变量?static 关键字修饰的变量或方法是属于类的,它属于类的变量。在编译时就已经确定了;而普通变量或方法是属于该由类生成的对象调用,需要在实例化后才能确定。因此,若static关键字修饰了方法的局部变量,一方面方法需要在实例化之后才能确定,另一方面static修饰的变量需要在编译时确定,这就会导致矛盾。
5、Java类的连接与初始化 (2013阿里笔试题解析) http://www.cnblogs.com/iceAeterNa/p/4876747.html
6、String和StringBuffer的区别:(1)、String为不可变字符串,StringBuffer为可变字符串;(2)、String重写了equals方法(如果String的对象调用equals方法比较的是值是否相等,而所有的==比较的都是引用地址是否指向同一个值。),StringBuffer比较的还是引用;(3)、在对字符串进行连接操作的时候StringBuffer的操作效率远比String高,因为String底层还是依赖StringBuffer实现的。
7、错误、编译期异常和运行时异常的区别:
-
Error和Exception都继承自Thorwable。
-
Error是错误,是不可挽回的,也就是说,出了Error程序就挂了,最常见的就是OutOfMemoryError。
-
编译时异常指的是我们必须在代码中显示的处理,或者try或者throw,处理完成后才能编译成功,常见的是IOException。
-
运行期异常指的是我们写的代码可以编译通过,但是如果运行时出现问题,则会出现运行期异常,最常见的就是NullPointerException、IndexOutOfBoundsException
8、==、equals、instanceof 和isInstance的区别:
public static void main(String[] args) {
String string = new String("Nice");
String string2 = new String("to");
String string3 = new String("meet");
String string4 = new String("meet");
System.out.println(string instanceof String);
System.out.println(string.getClass().isInstance(string2));
System.out.println(string3==string4);
System.out.println(string3.equals(string4));
}
out:
true instanceof表示:你是这个类么?或者你是这个类的派生类么?
true isInstance表示:自身类.class.isInstance(自身实例或子类实例) 返回true
false 比较的引用
true 比较的内容(String重写了equals方法,比较的是值)
9、Main函数的参数String[] args:
第一、程序使用者可以在命令行状态下向某个类传递参数。看下面的例子:
public class ArgsDemo {
public static void main(String[] args) {
String str = new String();
for (int i = 0; i < args.length; i++) {
System.out.println(args[i]);
str += args[i];
}
System.out.println(str);
}
}
使用javac ArgsDemo.java命令生成ArgsDemo.class文件;然后使用“java ArgsDemo 参数一 参数二 参数三 …”的格式向ArgsDemo类传递参数。该示例程序将首先输出参数,然后输出所有参数的和。比如java ArgsDemo a b c,将得到这样的输出:
a
b
c
abc
需要注意的是,如果这里的循环条件不是i <args.length,而是i <5,则在命令行中输入的参数必须是5个,否则将会报错,错误类型为:
Exception in thread “main” java.lang.ArrayIndexOutOfBoundException:3
at ArgsDemo.main(ArgsDemo.java:5)
第二、可以在另一个类中向包含main()的类传递参数,如下例:
public class A {
public static void main(String[] args)
{
for(int i=0;i <args.length;i++)
System.out.println(args[i]);
}
}
public class B {
public static void main(String[] args)
{
c = new A();
String[] b = {"111","222","333"};
c.main(b);
}
}
首先定义一个class A,在A中定义一个main()函数,在该函数中输出参数args。然后定义一个classB,在B中初始化一个A的实例c,然后向c传递参数,并且调用c的main方法打印出传入的参数值。输出结果如下:
111
222
333
由于main()函数是静态函数,即不需要实例化也能使用,所以B使用下面的写法也能完成相同的功能:
public class B {
public static void main(String[] args)
{
//A c = new A();
String[] b = {"111","222","333"};
A.main(b);
}
}
小结:参数args的主要作用是为程序使用者在命令行状态下与程序交互提供了一种手段。此外在其他类中直接使用main()函数,并传递参数也是可行的,虽然这种方法不太常用,但毕竟为我们提供了一种选择。
10、java线程池:
ava通过Executors提供四种线程池,分别为:
newCachedThreadPool创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。
newFixedThreadPool 创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。
newScheduledThreadPool 创建一个定长线程池,支持定时及周期性任务执行。
newSingleThreadExecutor 创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。
(1). newCachedThreadPool
创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程。示例代码如下:
线程池为无限大,当执行第二个任务时第一个任务已经完成,会复用执行第一个任务的线程,而不用每次新建线程。
(2). newFixedThreadPool
创建一个定长线程池,可控制线程最大并发数,超出的线程会在队列中等待。示例代码如下:
因为线程池大小为3,每个任务输出index后sleep 2秒,所以每两秒打印3个数字。
定长线程池的大小最好根据系统资源进行设置。如Runtime.getRuntime().availableProcessors()。可参考PreloadDataCache。
(3) newScheduledThreadPool
创建一个定长线程池,支持定时及周期性任务执行。延迟执行示例代码如下:
表示延迟3秒执行。
定期执行示例代码如下:
表示延迟1秒后每3秒执行一次。
ScheduledExecutorService比Timer更安全,功能更强大,后面会有一篇单独进行对比。
(4)、newSingleThreadExecutor
创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。示例代码如下:
结果依次输出,相当于顺序执行各个任务。
现行大多数GUI程序都是单线程的。Android中单线程可用于数据库操作,文件操作,应用批量安装,应用批量删除等不适合并发但可能IO阻塞性及影响UI线程响应的操作。
11、Callable 和 Runnable 的使用方法大同小异, 区别在于:
1.Callable 使用 call() 方法, Runnable 使用 run() 方法
2.call() 可以返回值, 而 run()方法不能返回。
3.call() 可以抛出受检查的异常,比如ClassNotFoundException, 而run()不能抛出受检查的异常。
Callable示例如下:
- class TaskWithResult implements Callable<String> {
- private int id;
- public TaskWithResult(int id) {
- this.id = id;
- }
- @Override
- public String call() throws Exception {
- return "result of TaskWithResult " + id;
- }
- }
- public class CallableTest {
- public static void main(String[] args) throws InterruptedException,
- ExecutionException {
- ExecutorService exec = Executors.newCachedThreadPool();
- ArrayList<Future<String>> results = new ArrayList<Future<String>>(); //Future 相当于是用来存放Executor执行的结果的一种容器
- for (int i = 0; i < 10; i++) {
- results.add(exec.submit(new TaskWithResult(i)));
- }
- for (Future<String> fs : results) {
- if (fs.isDone()) {
- System.out.println(fs.get());
- } else {
- System.out.println("Future result is not yet complete");
- }
- }
- exec.shutdown();
- }
- }
执行结果
- result of TaskWithResult 0
- result of TaskWithResult 1
- result of TaskWithResult 2
- result of TaskWithResult 3
- result of TaskWithResult 4
- result of TaskWithResult 5
- result of TaskWithResult 6
- result of TaskWithResult 7
- result of TaskWithResult 8
- result of TaskWithResult 9
Runnable示例:
- public class LiftOff implements Runnable {
- protected int countDown = 10;
- private static int taskCount = 0;
- private final int id = taskCount++;
- public LiftOff() {
- }
- public LiftOff(int countDown) {
- this.countDown = countDown;
- }
- public String status() {
- return "#" + id + "(" + (countDown > 0 ? countDown : "LiftOff! ") + ")";
- }
- @Override
- public void run() {
- while (countDown-- > 0) {
- System.out.print(status());
- Thread.yield();
- }
- System.out.println();
- }
- public static void main(String[] args) {
- ExecutorService exec = Executors.newFixedThreadPool(1);
- for (int i = 0; i < 5; i++) {
- exec.execute(new LiftOff());
- }
- exec.shutdown();
- }
- }
执行结果
- #0(9)#0(8)#0(7)#0(6)#0(5)#0(4)#0(3)#0(2)#0(1)#0(LiftOff! )
- #1(9)#1(8)#1(7)#1(6)#1(5)#1(4)#1(3)#1(2)#1(1)#1(LiftOff! )
- #2(9)#2(8)#2(7)#2(6)#2(5)#2(4)#2(3)#2(2)#2(1)#2(LiftOff! )
- #3(9)#3(8)#3(7)#3(6)#3(5)#3(4)#3(3)#3(2)#3(1)#3(LiftOff! )
- #4(9)#4(8)#4(7)#4(6)#4(5)#4(4)#4(3)#4(2)#4(1)#4(LiftOff! )
注意ExecutorService 在Callable中使用的是submit(), 在Runnable中使用的是 execute()
12.
Tomcat版本与Servlet、JSP等版本的支持关系
点击这里
未完待续....