目录
一、== 和 equals的区别
==: 它的作用主要是判断两个对象的地址是不是相等。即判断两个对象是不是同一个对象
(基本数据类型 == 比较的是值,引用数据类型 == 比较的是内存地址)
因为 Java 只有值传递,所以,对于 == 来说,不管是比较基本数据类型,还是引用数据类型的变量,其本质比较的都是地址。但是基本数据类型来说,值相同的变量,地址也一定相同,即值就等于变量地址,而引用类型变量存的值是对象的地址。
equals() : 它的作用也是判断两个对象是否相等,它不能用于比较基本数据类型的变量。equals()方法存在于Object类中,而Object类是所有类的直接或间接父类。
1、 ==和equals的本质区别
1.==比较的永远是地址
2.equals本质上也比较的是地址(调用的就是==),但是有些类重写了equals方法,达到比较对象内容的目的
2、==和equals用于String对象的比较。
代码:
public static void main(String[] args) {
String s = new String("abc");
String s1 = new String("abc");
System.out.println(s == s1);
System.out.println(s.equals(s1));
}
输出:
false
true
这很容易解释嘛,因为我们都知道==比较的是地址,equals比较的是字符串内容
String类的equals是因为被重写成了比较两个字符串的内容是否相等
3、==和equals用于Object对象的比较
代码:
public static void main(String[] args) {
Object s = new Object();
Object s1 = new Object();
System.out.println(s == s1);
System.out.println(s.equals(s1));
}
输出:
false
false
两个自定义对象内容相同,但是调用equals比较时却返回的是false了,因为没有重写equals方法,那么在调用equals方法的时候本质上是在调用父类Object的equals,而我们通过源码发现Object的equals方法比较的就是两个对象的地址。
4、例题
==,如果作用于基本数据类型的变量,则直接比较其存储的 “值”是否相等; 如果作用于引用类型的变量,则比较的是所指向的对象的地址
equals方法,注意:equals方法不能作用于基本数据类型的变量。
①Object类中,equals方法是用来比较两个对象的引用是否相等,即是否指向同一个对象。
②String类对equals方法进行了重写,用来比较指向的字符串对象所存储的字符串是否相等。其他的一些类诸如Double,Date,Integer等,都对equals方法进行了重写用来比较指向的对象所存储的内容是否相等
二、Hashtable 和 HashMap的区别
Hashtable:
(1)Hashtable 是一个散列表,它存储的内容是键值对(key-value)映射。
(2)Hashtable 的函数都是同步的,这意味着它是线程安全的。它的key、value都不可以为null。 (3)Hashtable直接使用对象的hashCode。
HashMap:
(1)由数组+链表组成的,基于哈希表的Map实现,数组是HashMap的主体,链表则是主要为了解决哈希冲突而存在的。
(2)不是线程安全的,HashMap可以接受为null的键(key)和值(value)。
(3)HashMap重新计算hash值 Hashtable,HashMap,Properties继承关系如下:
public class Hashtable<K,V> extends Dictionary<K,V> implements Map<K,V>, Cloneable, java.io.Serializable public class HashMap<K,V>extends AbstractMap<K,V> implements Map<K,V>,
Cloneable, Serializable java.lang.Objecct java.util.Dictionary<K,V> java.util.Hashtable<Object,Object> java.util.Properties
总结:
HashMap是线程安全的,HashMap的线程不安全
Properties 类 继承了 Hashtable 类,而 Hashtable 类则继承Dictionary 类
HashMap允许将 null 作为一个 entry 的 key 或者 value,而 Hashtable 不允许。
三、Instanceof
instance是java的二元运算符,用来判断他左边的对象是否为右面类(接口,抽象类,父类)的实例
我们考虑的时候,左边的对象如果是父类的引用指向子类的对象,我们用子类对象的范围来判断!
四、JSP内置对象
JSP内置对象和属性列举如下:
1.request对象 :客户端的请求信息被封装在request对象中,通过它才能了解到客户的需求,然后做出响应。它是HttpServletRequest类的实例。
2.response对象 :response对象包含了响应客户请求的有关信息,但在JSP中很少直接用到它。它是HttpServletResponse类的实例。
3.session对象 :session对象指的是客户端与服务器的一次会话,从客户连到服务器的一个WebApplication开始,直到客户端与服务器断开连接为止。它是HttpSession类的实例.
4.out对象 : out对象是JspWriter类的实例,是向客户端输出内容常用的对象
5.page对象 :page对象就是指向当前JSP页面本身,有点象类中的this指针,它是java.lang.Object类的实例
6.application对象 : application对象实现了用户间数据的共享,可存放全局变量。它开始于服务器的启动,直到服务器的关闭,在此期间,此对象将一直存在;这样在用户的前后连接或不同用户之间的连接中,可以对此对象的同一属性进行操作;在任何地方对此对象属性的操作,都将影响到其他用户对此的访问。服务器的启动和关闭决定了application对象的生命。它是ServletContext类的实例。
7.exception对象 : exception对象是一个例外对象,当一个页面在运行过程中发生了例外,就产生这个对象。如果一个JSP页面要应用此对象,就必须把isErrorPage设为true,否则无法编译。他实际上是java.lang.Throwable的对象
8.pageContext对象: pageContext对象提供了对JSP页面内所有的对象及名字空间的访问,也就是说他可以访问到本页所在的SESSION,也可以取本页面所在的application的某一属性值,他相当于页面中所有功能的集大成者,它的本 类名也叫pageContext。
9.config对象 :config对象是在一个Servlet初始化时,JSP引擎向它传递信息用的,此信息包括Servlet初始化时所要用到的参数(通过属性名和属性值构成)以及服务器的有关信息(通过传递一个ServletContext对象)
五、socket连接
服务器端:ServerSocket提供的实例 ServerSocket server = new ServerSocket(端口号)
客户端:Socket提供的实例 Socket client = new Socket(IP地址,端口号)
六、实现多线程的方法
1.继承Thread类
2.实现Runnable接口
3.实现Callable接口,然后使用 FutureTask包装,因为Callable接口没有实现Runnable接口不能做为Thread的target,而FutureTask是在Java程序中可以取消的异步运算,有可以开始,取消运算,查询运算是否结束,获得查询结果的功能,特别注意的是,如果查询结果时,运算还没完成则会阻塞线程。
4.使用,java.util.current.ThreadPoolExecutor来获取线程,执行多线程
七、关于java classloader
JDK中提供了三个ClassLoader,根据层级从高到低为:
Bootstrap ClassLoader,主要加载JVM自身工作需要的类。
Extension ClassLoader,主要加载%JAVA_HOME%\lib\ext目录下的库类。
Application ClassLoader,主要加载Classpath指定的库类,一般情况下这是程序中的默认类加载器,也是ClassLoader.getSystemClassLoader() 的返回值。(这里的Classpath默认指的是环境变量中配置的Classpath,但是可以在执行Java命令的时候使用-cp 参数来修改当前程序使用的Classpath)
JVM加载类的实现方式,我们称为 双亲委托模型:
如果一个类加载器收到了类加载的请求,他首先不会自己去尝试加载这个类,而是把这个请求委托给自己的父加载器,每一层的类加载器都是如此,因此所有的类加载请求最终都应该传送到顶层的Bootstrap ClassLoader中,只有当父加载器反馈自己无法完成加载请求时,子加载器才会尝试自己加载。
双亲委托模型的重要用途是为了解决类载入过程中的安全性问题。
假设有一个开发者自己编写了一个名为Java.lang.Object的类,想借此欺骗JVM。现在他要使用自定义ClassLoader来加载自己编写的java.lang.Object类。然而幸运的是,双亲委托模型不会让他成功。因为JVM会优先在Bootstrap ClassLoader的路径下找到java.lang.Object类,并载入它