分析:
在类方法(static 方法)中,
-
不能使用super、this 关键字
-
不能引用实例变量,‘
-
不能调用类方法
不考虑修饰的话 -
实例方法可以通过super.方法名,对象名.方法名调用父类的实例方法
-
实例方法可以通过类名.方法名,super.方法名调用父类的静态方法
-
实例方法通过this.方法名调用本类的其他方法
-
本类的静态方法还可以用类名.方法名调用
在本题中,如果是私有的,ABC都不能访问。
分析: 5 >> 2 相当于 5除于2的平方,等于1 ,>>> 表示无符号 右移,高位用0 填充,0001 右移两位 0000,所以答案选 A
分析:
A,抽象类和接口都不可以实例化。
B,final类不能被继承。
C,abstract不能和final共用修饰类。
D,抽象类中可以没有抽象方法,有抽象方法的类一定是抽象类。
注意: abstract是用来修饰类和方法的:- 修饰方法:abstract不能和private、final、static共用。
- 修饰外部类:abstract不能和final、static共用。(外部类的访问修饰符只能是默认和public)
- 修饰内部类:abstract不能和final共用。(内部类四种访问修饰符都可以修饰)
分析:
关于封装:
封住、继承、多态是面向对象的三大特征,其重要性与使用频率不言而喻。------所以B错误。
1 、什么是封装?
封装就是将属性私有化,提供公有的方法访问私有属性。------------------- 所以CD错误。
做法就是:修改属性的可见性来限制对属性的访问,并为每个属性创建一对取值( getter )方法和赋值( setter )方法,用于对这些属性的访问。
如: private String name;
public String getName(){
return;
}
public void setName(String name){
this.name=name;
}
- 为什么需要封装?
- 通过封装,可以实现对属性的数据访问限制,同时增加了程序的可维护性,
- 由于取值方法和赋值方法隐藏了实现的变更,因此并不会影响读取或修改该属性的类,避免了大规模的修改,程序的可维护性增强
封装主要是隐藏内部代码
继承主要是复用现有代码
多态主要是改写对象行为
分析:
- String,StringBuffer,StringBuilder,都实现了CharSequence 接口
- String 是个不可继承类(final修饰),也是个不可变类(内部char数组被final修饰)
- StringBuffer和StringBuilder 内部是一般的动态数组,所以可变,前者是线程安全的。因为方法都被synchronized 修饰了。
Servlet的生命周期 - 加载:容器通过类加载器使用Servlet 类对应的文件加载servlet
- 创建:通过调用servlet 构造函数创建一个servlet 对象
- 初始化:调用 init 方法初始化,这个方法是在Servlet已经被创建,但在向客户端提供服务之前调用。
- 处理客户请求:每当有一个客户请求,容器会创建一个线程来处理客户请求。接着调用Service() 方法来响应客户端请求(Service()方法根据请求的method属性来调用doGet()和doPost()
- 卸载:容器在卸载Servlet之前需要调用destory方法让servlet自己释放其占用的资源`
class Base
{
public void method()
{
System.out.println("Base");
}
}
class Son extends Base
{
public void method()
{
System.out.println("Son");
}
public void methodB()
{
System.out.println("SonB");
}
}
public class Test01
{
public static void main(String[] args)
{
Base base = new Son();
base.method();
base.methodB();
}
}
分析:
Base base=new Son();
这句new 了一个派生类,赋值给基类,所以下面的操作编译器认base对象就是Base类型的。Base类中不存在methodB() 方法,所以编译不通过。
Base base=new Son(); 是多态的表示形式。父类对象调用了子类创建了Son对象。
base调用的method()方法就是调用了子类重写的method()方法。
而此时base还是属于Base对象,base调用methodB()时Base对象里没有这个方法,所以编译不通过。
要想调用的话需要先通过SON son=(SON)base;强制转换,然后用son.methodB()调用就可以了。
- HttpServlet 是GenericServlet 的子类
- GenericServlet 是个抽象类,必须给出子类才能实例化。他给出了设计servlet的一些骨架,定义了servet 生命周期, 还有一些得到名字、配置、初始化参数的方法,其设计的是和应用层协议无关的,也就是说,你有可能用非http协议实现它。
- HttpServlet是子类,当然就具有GenericServlet的一切特性,还添加了doGet, doPost, doDelete, doPut, doTrace等方法对应处理http协议里的命令的请求响应过程
- 一般没有特殊需要,自己写的Servlet都扩展HttpServlet 。
分析: - LinkedList 是实现了List 接口,继承了AbstractSequentialList
- AbstractSet 是实现了Set 接口,继承了AbstractCollection(抽象类)
- HashSet 实现了Set 接口,继承自AbstractSet,
- WeakMap 不存在于java 集合框架,只有一个叫做WeakHashMap(继承自AbstractMap)
函数重载的时候不以返回类型作为区分。
分析:
- 抽象类不能被实例化,如果被实例化,就会报错,编译无法通过。只有抽象类的非抽象子类可以创建对象
- 抽象类中不一定包含抽象方法,但是有抽象方法的必定是抽象类
- 抽象类中的抽象方法只是生命,不包含方法体,就是不给出方法的具体实现也就是方法的具体功能
- 构造方法,类方法(用static 修饰的方法)不能声明为抽象方法
- 抽象类的子类必须给出抽象类中的抽象方法的具体实现,除非该子类也是抽象类
分析: main() 函数即主函数,是一个前台进程,前台进程是程序中必须执行完成的,而后台线程则是java 中所有前台线程结束后,不管有没有完成。后台线程主要用于内存分配等方面
前台线程和后台线程的区别和联系 - 后台线程不会阻止进程的终止,属于某个进程的所有前台线程都终止后,该进程就会被终止。所有剩余的后台线程都会停止且不会完成
- 可以在任何时候将前台线程修改为后台线程,方式是设置Thread.isBackground 属性
- 不管是前台线程还是后台线程,如果线程内出现了异常,都会导致进程的终止
- 托管线程池中的线程都是后台线程,使用new Thread方式创建的线程默认都是前台线程。
说明:
- 应用程序的主线程以及使用Thread 构造的线程都默认为前台线程
- 使用Thread 建立的线程默认情况下是前台线程,在进程中,只要有一个前台线程未退出,进程就不会终止。主线程就是一个前台线程。而后台线程不管线程是否结束,只要所有的前台线程都退出(包括正常退出和异常退出)后,进程就会自动终止。一般后台线程用于处理时间较短的任务,如在一个Web服务器中可以利用后台线程来处理客户端发过来的请求信息。而前台线程一般用于处理需要长时间等待的任务,如在Web服务器中的监听客户端请求的程序,或是定时对某些系统资源进行扫描的程序。
分析:
A:错误 {company:4399} 首先,其为json对象。但json对象要求属性必须加双引号。
B:正确
C:错误 {[4399,4399,4399]} 。使用 {} 则为json对象。json对象必须由一组有序的键值对组成。
D:正确。
都是Throwable 的子类:
- Exception(异常):是程序本身可以处理的异常
- Error(错误):是程序无法处理的错误。这些错误表示故障发生于虚拟机自身,或者发生在虚拟机试图执行应用时,一般不需要程序处理。
- 检查异常(编译器要求必须处置的异常):除了Error,RuntimeException 及其子类以外,其他的Exception 类及其子类都属于可查异常。这种异常的特点是java编译器会检查他,也就是说,当程序中可能出现这类异常,要么用try-catch语句捕获,要么用throws子句声明抛出,否则编译不会通过
- 非检查编译(编译器不要求处置的异常)包括运行时异常(RuntimeException与其子类)和错误(Error)。
内部类
- 静态内部类:
静态内部类本身可以访问外部的静态资源,包括静态私有资源。但是不能访问非静态资源,可以不依赖外部类实例而实例化。 - 成员内部类:
成员内部类本身可以访问外部的所有资源,但是自身不能定义静态资源,因为其实例化本身就还依赖着外部类。 - 局部内部类:
- 局部内部类就像一个局部方法,不能被访问修饰符修饰,也不能被static修饰。
- 局部内部类只能访问所在代码块或者方法中被定义为final的局部变量。
- 匿名内部类:
- 没有类名的内部类,不能使用class,extends和implements,没有构造方法。
- 多用于GUI中的事件处理。
- 不能定义静态资源
- 只能创建一个匿名内部类实例。
- 一个匿名内部类一定是在new后面的,这个匿名类必须继承一个父类或者实现一个接口。
- 匿名内部类是局部内部类的特殊形式,所以局部内部类的所有限制对匿名内部类也有效。
分析:
- forward: 服务器获取跳转页面内容传给用户,用户地址栏不变
- redirect: 服务器向用户发送转向的地址,redirect 后地址栏变成新的地址
分析:
- sleep:会使当前线程睡眠指定时间,不释放锁
- yield: 会使当前线程重回到可执行状态,等待CPU 的调度,不释放锁
- wait: 会使当前线程回到线程池中等待,释放锁,当被其他线程使用notify,notifyAll 唤醒时进入可执行状态
- join: 当前线程调用,某线程.join() 时会使当前线程等待某线程执行完毕再结束,底层调用了wait,释放锁。
分析:(D:以上都不对)
此题涉及到java中的自动装箱和自动拆箱:
- ++a 先是触发拆箱操作Byte.byteValue,得到基本类型的值127,然后执行+1 操作,使得值变为-128,最后出发装箱操作Byte.valueOf将value=-128 的Byte 对象赋值给a。
- 包装类的值都是final不可变的,对于++a或者是a++,只是新创建了一个对象,然后把引用传给了原对象句柄,在函数中操作,只是形参的临时句柄改变了指向,实参的句柄还是指原来的对象。所以即使不是a=a++这种,a的值在add之后也是不会变的。
分析:
- 常量池中的字符串,只有变量名不同是可以用双等号判断是否相等,内存都是常量池中的字符串。
- new 出来的字符串,只能用equals,用双等号是不相等的,因为是两个内存对象。
- String 类重写equals 方法后,先会判断c是否是String类型的实例,这里的c是char数组,所以返回false.
public class HelloWorld {
public static void main(String []args) {
String s = "hello";
String t = "hello";
char c[] = {'h','e','l','l','o'} ;
System.out.println(s.equals(t));
//c++中定义的东西,不要在java中混为一谈。(对这句话我不负责任)
System.out.println(t.equals(c));
System.out.println(s==t);
System.out.println(t.equals(new String("hello")));
//这个不相等,因为语句中new的字符串不在常量池,是在堆
System.out.println(t==new String("hello"));
//这样可以判断字符数组与字符串是否包含同样的字符序列
System.out.println(t.equals(new String(c)));
}
}
-
初始化阶段:在下列时刻servlet容器装载servlet
-
servlet 容器启动时,自动装载某些servlet
-
在servlet 容器启动后,客户首次向servlet发送请求
-
servlet 类文件被更新之后,重新装载servlet。
Servlet 被装载之后,servlet容器创建一个servlet对象并调用servlet的init方法,在servleet生命周期内,init方法只能被调用一次。
Servlet工作原理:客户端发起一个请求,servlet调用service()方法时请求进行响应,service对请求的方式进行了匹配,选择调用dopost或者doget等这些方法,然后进入对应方法中调用逻辑层的方法,实现对客户的响应。 -
响应客户请求:对于用户到达servlet的请求,servlet容器会创建特定于该请求的servletrequest和servletresponse对象,然后调用servlet的service方法,service方法从servletrequest对象中获取客户请求的信息,处理该请求,并且通过servletresponse 对象向客户端返回响应信息。
-
终止:当web应用终止或者servlet容器终止或servlet容器重新装载servlet新实例时,servlet容器会调用servlet对象的destory方法,在destory方法中释放servlet占用的资源。
分析:
A:属于运行时常量池导致的溢出,设置-XX:MaxPermSize可以解决这个问题。
B:属于堆空间不足导致的错误,解决方式和C相同
C:属于java堆内存问题,一般的手段是通过内存映像分析工具,对Dump出来的堆转储存快照进行分析,重点是确认内存中的对象是否是有必要的,也就是要判断是出现了内存泄漏,还是出现了内存溢出,如果是内存泄漏,通过工具检查泄漏对象 GC Roots 的引用链信息,可以准确的确定出泄漏代码的位置,不存在泄漏,就应该检查虚拟机的堆参数,如果可以继续调大,可以设置-Xmx解决问题。
D:指当虚拟机不能分配新的线程本地空间的时候错误信息,此错误是线程申请的一个新的TLA时产生的,这个异常一般只会发生在jRockit虚拟机,只有过于绝对。
分析:
B:数组的长度是固定的
D:int[] array=new array[100]
E: 数组是一种引用数据类型,那么他肯定是继承Object类的,所以里面有equals()方法,但是肯定没有重写过,因此它并不是比较数组内的内容。使用Arrays.equals()是比较两个数组中的内容
分析:
java.lang.NullPoninterException:变量未被初始化、对象未被赋值、对象为空(俗称的空指针异常)
java.lang.NumberFormatException:数据格式转换失败(Integer 的取值范围为-127-128,超过范围都会访问false)
java.lang.RuntimeException: 运行时异常
java.lang.ArrayIndexOutOfBoundsException:数组下标越界。
分析:
- 类中变量:除了private权限外,其他权限的变量(没有表示默认(default),均可用“对象.变量名”来调用。对于private变量,即使使用static,也不能用“类.变量名”来调用私有变量。只能通过类中的public get()方法来调用。
- 类中方法:除了private权限外,其他权限的方法(没有表示默认(default)),均可以用“对象.方法名”来调用。private方法可以用java反射机制调用。当然如果用private修饰方法,该方法只在类的内部调用。其中比较著名的就是单例模式中的私有构造方法。
- static属性:static方法在编译期就已经生成了,其他方法在运行期生成。非私有的static方法可以用"类.方法名"调用。但是私有的static 变量和方法都是不可能被调用的,虽然private static 这种写法很少见,但仍然存在,且编译器不会报错。
分析:
按照是否直接与特定的地方(如磁盘、内存、设备等)相连,分为节点流和处理流两类。
- 节点流:可以从或向一个特定的地方(节点)读写数据。如FileReader
- 处理流:是对一个已存在的流的连接和封装,通过所封装的流的功能调用实现数据读写。如BufferedReader.处理流的构造方法总是要带一个其他的流对象做参数。一个流对象经过其他流的多次包装,称为流的链接。
Java 常用的节点流
- 文件FileInputStream、FileOutputStream、FileReader、FileWriter文件进行处理的节点流。
- 字符串StringReader、StringWriter 对字符串进行处理的节点流
- 数组ByteArrayInputStream、ByteArrayOutputStream、CharArrayWriter对数组进行处理的节点流(对应的不再是文件,而是内存中的一个数组)。
- 管道PipesInputStream、PipedOutputStream、PipedReader、PipedWriter对管道进行处理的节点流。
常用处理流(关闭处理流使用关闭里面的节点流):
- 缓冲流:BufferedInputStream、BufferedOutputStream、BufferedReader、BufferedWriter 增加缓冲功能,避免频繁读写硬盘
- 转换流:InputStreamReader、OutputStreamReader实现字节流和字符流之间的转换。
- 数据流:DataInputStream、DataOutputStream 等都提供将基础数据类型写入到文件中,或者读取出来。
流的关闭顺序: