Java-刷题知识点笔记-P6

1.jvm

1.1命令

  1. jps:查看本机java进程信息。
  2. jstack:打印线程的栈信息,制作线程dump文件。
  3. jmap:打印内存映射,制作堆dump文件
  4. jstat:性能监控工具
  5. jhat:内存分析工具
  6. jconsole:简易的可视化控制台
  7. jvisualvm:功能强大的控制台

1.2锁synchronized

对象锁

  • 同步代码块(synchronized(this),synchronized(类实例对象),锁是小括号()中的实例对象)
  • 同步非静态方法(synchronized method),锁的是当前对象的实例对象

获取类锁

  • 同步代码块(synchronized(类.class)),锁是最小括号 () 中的类对象(Class对象)
  • 同步静态方法(synchronized static method),锁是当前对象的类对象(Class 对象)

总结

  1. 有线程访问对象的同步代码块时,另外的线程可以访问该对象的非同步代码块
  2. 若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象的同步代码块的线程会被阻塞。
  3. 若锁住的是同一个对象,一个线程在访问对象的同步方法时,另一个访问对象的同步方法的线程会被阻塞。
  4. 若锁住的是同一个对象,一个线程在访问对象的同步代码块时,另一个访问对象同步方法的线程会被阻塞,反之亦然。
  5. 同一个类的不同对象的锁互不干扰
  6. 类锁由于也是一种特殊的对象锁,因此表现和上述一致,而由于一个类只有一把对象锁,所以同一个类的不同对象使用类锁将会是同步的
  7. 类锁和对象锁互不干扰

2.数据库

2.1系数据模型和对象数据模型之间有以下对应关系:

  • 表对应类
  • 记录对应对象
  • 表的字段对应类的属性

2.2 jdbc statement

Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程

2.2.1Statement

  • Statement继承自Wrapper
  • Statement接口提供了执行语句和获取结果的基本方法;
  • a.Statement:
    普通的不带参的查询SQL;支持批量更新,批量删除;
  • Statement每次执行sql语句,数据库都要执行sql语句的编译 , 最好用于仅执行一次查询并返回结果的情形,效率高PreparedStatement。
  • 创建Statement是不传参的,PreparedStatement是需要传入sql语句

2.2.2PreparedStatement

  • PreparedStatement继承自Statement

  • PreparedStatement接口添加了处理 IN 参数的方法;

  • b.PreparedStatement:
    可变参数的SQL,编译一次,执行多次,效率高;
    安全性好,有效防止Sql注入等问题;
    支持批量更新,批量删除;

  • PreparedStatement是预编译的,使用PreparedStatement有几个好处

    1. 在执行可变参数的一条SQL时,=PreparedStatement比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率要高。
    2. 安全性好,有效防止Sql注入等问题。
    3. 对于多次重复执行的语句,使用PreparedStament效率会更高一点,并且在这种情况下也比较适合使用batch;
    4. 代码的可读性和可维护性。

2.2.3CallableStatement

  • CallableStatement继承自PreparedStatement。
  • CallableStatement接口添加了处理 OUT 参数的方法。
  • c.CallableStatement:
    继承自PreparedStatement,支持带参数的SQL操作;
    支持调用存储过程,提供了对输出和输入/输出参数(INOUT)的支持;

2.3结果集(ResultSet)

  • ResultSet是数据中查询结果返回的一种对象,可以说结果集是一个存储查询结果的对象,但是结果集并不仅仅具有存储的功能,他同时还具有操纵数据的功能,可能完成对数据的更新等。

  • 结果集读取数据的方法主要是getXXX() ,他的参数可以使整型表示第几列(是从1开始的),还可以是列名。XXX可以代表的类型有:基本的数据类型如整型(int),布尔型(Boolean),浮点型(Float,Double)等,比特型(byte),还包括一些特殊的类型,如:日期类型(java.sql.Date),时间类型(java.sql.Time),时间戳类型 (java.sql.Timestamp),大数型(BigDecimal和BigInteger等)等。还可以使用getArray(int colindex/String columnname),通过这个方法获得当前行中,colindex所在列的元素组成的对象的数组。使用getAsciiStream(int colindex/String colname)可以获得该列对应的当前行的ascii流。也就是说所有的getXXX方法都是对当前行进行操作。

  • 结果集从其使用的特点上可以分为四类,这四类的结果集的所具备的特点都是和Statement语句的创建有关,因为结果集是通过Statement语句执行后产生的,所以可以说,结果集具备何种特点,完全决定于Statement,当然我是说下面要将的四个特点,在Statement创建时包括三种类型。首先是无参数类型的,他对应的就是下面要介绍的基本的ResultSet对应的Statement。下面的代码中用到的Connection并没有对其初始化,变量conn代表的就是Connection对应的对象。SqlStr代表的是响应的SQL语句。

2.3.1 最基本的ResultSet

之所以说是最基本的ResultSet是因为,这个ResultSet他起到的作用就是完成了查询结果的存储功能,而且只能读去一次,不能够来回的滚动读取。这种结果集的创建方式如下:

Statement st = conn.CreateStatement
ResultSet rs = Statement.excuteQuery(sqlStr);

由于这种结果集不支持,滚动的读去功能所以,如果获得这样一个结果集,只能使用它里面的next()方法,逐个的读去数据。

2.3.2可滚动的ResultSet类型

这个类型支持前后滚动取得纪录next()、previous(),回到第一行first(),同时还支持要去的ResultSet中的第几行 absolute(int n),以及移动到相对当前行的第几行relative(int n),要实现这样的ResultSet在创建Statement时用如下的方法。

Statement st = conn. createStatement (int resultSetType, int resultSetConcurrency)
ResultSet rs = st.executeQuery(sqlStr)

其中两个参数的意义是:
resultSetType 是设置 ResultSet 对象的类型可滚动,或者是不可滚动。取值如下:
ResultSet.TYPE_FORWARD_ONLY 只能向前滚动
ResultSet.TYPE_SCROLL_INSENSITIVE 和 Result.TYPE_SCROLL_SENSITIVE 这两个 方法都能够实现任意的前后滚动,使用各种移动的 ResultSet 指针的方法。二者的区别在于前者对于修改不敏感,而后者对于修改敏感。
resultSetConcurency 是设置 ResultSet 对象能够修改的,取值如下:
ResultSet.CONCUR_READ_ONLY 设置为只读类型的参数。
ResultSet.CONCUR_UPDATABLE 设置为可修改类型的参数。
所以如果只是想要可以滚动的类型的 Result 只要把 Statement 如下赋值就行了。

Statement st = conn.createStatement(Result.TYPE_SCROLL_INSENITIVE,
                          ResultSet.CONCUR_READ_ONLY);
ResultSet rs = st.excuteQuery(sqlStr)

用这个 Statement 执行的查询语句得到的就是可滚动的 ResultSet 。

2.3.3可更新的ResultSet

这样的ResultSet对象可以完成对数据库中表的修改,但是我知道ResultSet只是相当于数据库中表的视图,所以并不时所有的ResultSet只要设置了可更新就能够完成更新的,能够完成更新的ResultSet的SQL语句必须要具备如下的属性:
a 、只引用了单个表。
b 、不含有join或者group by子句。
c 、那些列中要包含主关键字。
具有上述条件的,可更新的ResultSet可以完成对数据的修改,可更新的结果集的创建方法是:

Statement st = createstatement(Result.TYPE_SCROLL_INSENSITIVE,Result.CONCUR_UPDATABLE)

2.3.4可保持的ResultSet

正常情况下如果使用Statement执行完一个查询,又去执行另一个查询时这时候第一个查询的结果集就会被关闭,也就是说,所有的Statement的查询对应的结果集是一个,如果调用Connection的commit()方法也会关闭结果集。可保持性就是指当ResultSet的结果被提交时,是被关闭还是不被关闭。JDBC2.0和1.0提供的都是提交后ResultSet就会被关闭。不过在JDBC3.0中,我们可以设置ResultSet是否关闭。要完成这样的ResultSet的对象的创建,要使用的Statement的创建要具有三个参数,这个Statement的创建方式也就是,我所说的 Statement的第三种创建方式。

当使用ResultSet的时候,当查询出来的数据集记录很多,有一千万条的时候,那rs所指的对象是否会占用很多内存,如果记录过多,那程序会不会把系统的内存用光呢

不会的,ResultSet表面看起来是一个记录集,其实这个对象中只是记录了结果集的相关信息,具体的记录并没有存放在对象中,具体的记录内容知道你通过next方法提取的时候,再通过相关的getXXXXX方法提取字段内容的时候才能从数据库中得到,这些并不会占用内存,具体消耗内存是由于你将记录集中的数据提取出来加入到你自己的集合中的时候才会发生,如果你没有使用集合记录所有的记录就不会发生消耗内存厉害的情况。

3.hashMap和hashtable

3.1关于HashMap

  • HashMap实际上是一个“链表散列”的数据结构,即数组和链表的结合体。
  • HashMap的底层结构是一个数组,数组中的每一项是一条链表。
  • HashMap的实例有俩个参数影响其性能: “初始容量” 和 装填因子。
  • HashMap实现不同步,线程不安全。 HashTable线程安全
  • HashMap中的key-value都是存储在Entry中
  • HashMap可以存null键和null值,不保证元素的顺序恒久不变,它的底层使用的是数组和链表,通过hashCode()方法和equals方法保证键的唯一性
  • 解决冲突主要有三种方法:定址法,拉链法,再散列法。
  • HashMap是采用拉链法解决哈希冲突的。 注: 链表法是将相同hash值的对象组成一个链表放在hash值对应的槽位;
  • 用开放定址法解决冲突的做法是:当冲突发生时,使用某种探查(亦称探测)技术在散列表中形成一个探查(测)序列。 沿此序列逐个单元地查找,直到找到给定的关键字,或者碰到一个开放的地址(即该地址单元为空)为止(若要插入,在探查到开放的地址,则可将待插入的新结点存人该地址单元)。
  • 拉链法解决冲突的做法是: 将所有关键字为同义词的结点链接在同一个单链表中 。若选定的散列表长度为m,则可将散列表定义为一个由m个头指针组成的指针数 组T[0…m-1]。凡是散列地址为i的结点,均插入到以T[i]为头指针的单链表中。T中各分量的初值均应为空指针。在拉链法中,装填因子α可以大于1,但一般均取α≤1。拉链法适合未规定元素的大小。

3.1Hashtable和HashMap的区别

  • 继承不同。

    public class Hashtable extends Dictionary implements Map 
    public class HashMap extends  AbstractMap implements Map
    
  • Hashtable中的方法是同步的,而HashMap中的方法在缺省情况下是非同步的。在多线程并发的环境下,可以直接使用Hashtable,但是要使用HashMap的话就要自己增加同步处理了。

  • Hashtable 中, key 和 value 都不允许出现 null 值在 HashMap 中, null 可以作为键,这样的键只有一个;可以有一个或多个键所对应的值为 null 。当 get() 方法返回 null 值时,即可以表示 HashMap 中没有该键,也可以表示该键所对应的值为 null 。因此,在 HashMap 中不能由 get() 方法来判断 HashMap 中是否存在某个键, 而应该用 containsKey() 方法来判断。

  • 两个遍历方式的内部实现上不同。Hashtable、HashMap都使用了Iterator。而由于历史原因,Hashtable还使用了Enumeration的方式 。

  • 哈希值的使用不同,HashTable直接使用对象的hashCode。而HashMap重新计算hash值。

  • Hashtable和HashMap它们两个内部实现方式的数组的初始大小和扩容的方式。HashTable中hash数组默认大小是11,增加的方式是old*2+1。HashMap中hash数组的默认大小是16,而且一定是2的指数。

  • 注: HashSet子类依靠hashCode()和equal()方法来区分重复元素。HashSet内部使用Map保存数据,即将HashSet的数据作为Map的key值保存,这也是HashSet中元素不能重复的原因。而Map中保存key值的,会去判断当前Map中是否含有该Key对象,内部是先通过key的hashCode,确定有相同的hashCode之后,再通过equals方法判断是否相同。

4.Ant与Maven

Ant和Maven都是基于Java的构建(build)工具。理论上来说,有些类似于(Unix)C中的make ,但没有make的缺陷。Ant是软件构建工具,Maven的定位是软件项目管理和理解工具。

4.1Ant

Ant的作用:是一种基于Java的build工具

  • 能够用ant编译java类。生成class文件
  • ant能够自己定义标签、配置文件,用于构建。
  • ant能够把相关层构建成jar包 。
  • ant把整个项目生成web包。并公布到Tomcat
  • Ant 没有正式的约定如一个一般项目的目录结构,你必须明确的告诉 Ant 哪里去找源代码

Ant的长处

  • 跨平台性:Ant是纯Java语言编写的,因此具有非常好的跨平台性。

  • 操作简单:Ant是由一个内置任务和可选任务组成的。Ant执行时须要一个XML文件(构建文件)。

  • Ant通过调用target树,就能够运行各种task:每一个task实现了特定接口对象。因为Ant构建文件时-

  • XML格式的文件。所以非常easy维护和书写,并且结构非常清晰。

  • Ant能够集成到开发环境中:因为Ant的跨平台性和操作简单的特点。它非常easy集成到一些开发环境中去。

4.2Maven

Maven的作用: 除了以程序构建能力为特色之外,还提供高级项目管理工具。

Maven除了具备Ant的功能外。还添加了下面基本的功能:

  • 使用Project Object Model来对软件项目管理。
  • 内置了很多其它的隐式规则,使得构建文件更加简单。
  • 内置依赖管理和Repository来实现依赖的管理和统一存储;
  • 内置了软件构建的生命周期;

Maven的长处

  • 拥有约定,知道你的代码在哪里,放到哪里去
  • 拥有一个生命周期,比如运行 mvn install就能够自己主动运行编译,測试。
  • 打包等构建过程仅仅须要定义一个pom.xml,然后把源代码放到默认的文件夹,Maven帮你处理其它事情拥有依赖管理。仓库管理

5.jvm虚拟机

在这里插入图片描述 JAVA的JVM的内存可分为3个区:堆(heap)、栈(stack)和方法区(method)

5.1栈区

  1. 每个线程包含一个栈区,栈中只保存方法中(不包括对象的成员变量)的基础数据类型和自定义对象的引用(不是对象),对象都存放在堆区中
  2. 每个栈中的数据(原始类型和对象引用)都是私有的,其他栈不能访问。
  3. 栈分为3个部分:基本类型变量区、执行环境上下文、操作指令区(存放操作指令)。

5.2堆区

  1. 存储的全部是对象实例,每个对象都包含一个与之对应的class的信息(class信息存放在方法区)。
  2. jvm只有一个堆区(heap)被所有线程共享,堆中不存放基本类型和对象引用,只存放对象本身,几乎所有的对象实例和数组都在堆中分配。

5.3方法区

  1. 又叫静态区,跟堆一样,被所有的线程共享
  2. 它用于存储已经被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

5.4垃圾回收

5.4.1两个最基本的java回收算法:复制算法和标记清理算法

  • 复制算法:两个区域A和B,初始对象在A,继续存活的对象被转移到B。此为新生代最常用的算法
  • 标记清理:一块区域,标记可达对象(可达性分析),然后回收不可达对象,会出现碎片,那么引出
  • 标记-整理算法:多了碎片整理,整理出更大的内存放更大的对象

5.4.2两个概念:新生代和年老代

在这里插入图片描述

新生代:初始对象,生命周期短的
永久代:长时间存在的对象
整个java的垃圾回收是新生代和年老代的协作,这种叫做分代回收。

5.4.3各种收集器

  • Serial New收集器是针对新生代的收集器,采用的是复制算法
  • Parallel New并行)收集器,新生代采用复制算法老年代采用标记整理
  • Parallel Scavenge(并行)收集器,针对新生代,采用复制收集算法
  • Serial Old(串行)收集器,新生代采用复制老年代采用标记整理
  • Parallel Old(并行)收集器,针对老年代,标记整理
  • CMS收集器,基于标记清理
  • G1收集器:整体上是基于标记整理局部采用复制
    综上:新生代基本采用复制算法,老年代采用标记整理算法。cms采用标记清理。

5.5sleep()|wait()|yield|join|

  1. sleep()方法

    在指定时间内让当前正在执行的线程暂停执行,但不会释放“锁标志”。不推荐使用。

    sleep()使当前线程进入阻塞状态,在指定时间内不会执行。

  2. wait()方法

    在其他线程调用对象的notify或notifyAll方法前,导致当前线程等待。线程会释放掉它所占有的“锁标志”,从而使别的线程有机会抢占该锁。

    当前线程必须拥有当前对象锁。如果当前线程不是此锁的拥有者,会抛出IllegalMonitorStateException异常。

    唤醒当前对象锁的等待线程使用notify或notifyAll方法,也必须拥有相同的对象锁,否则也会抛出IllegalMonitorStateException异常。

    waite()和notify()必须在synchronized函数或synchronized block中进行调用。如果在non-synchronized函数或non-synchronized block中进行调用,虽然能编译通过,但在运行时会发生IllegalMonitorStateException的异常。

  3. yield方法

    暂停当前正在执行的线程对象。

    yield()只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态后马上又被执行。

    yield()只能使同优先级或更高优先级的线程有执行的机会不释放锁

  4. join方法

    等待该线程终止。

    等待调用join方法的线程结束,再继续执行。如:t.join();//主要用于等待t线程运行结束,若无此句,main则会执行完毕,导致结果不可预测。底层调用了wait,释放锁

5.6内存溢出

  • java程序内存泄露的最直接表现是
  • java是自动管理内存的,通常情况下程序运行到稳定状态,内存大小也达到一个 基本稳定的值
    但是内存泄露导致Gc不能回收泄露的垃圾,内存不断变大.
    最终超出内存界限,抛出OutOfMemoryExpection

6.Web

后端获取数据,向前端输出的过程中,输出前应该采用信息安全部发布的XSSFilter进行相应编码

6.1weblogic中开发消息Bean时的persistent与non-persisten的差别

  • persistent方式的MDB可以保证消息传递的可靠性,也就是如果EJB容器出现问题而JMS服务器依然会将消息在此MDB可用的时候发送过来
  • non-persistent方式的消息将被丢弃。

6.2Web工程的目录结构

在这里插入图片描述

  1. /WEB-INF/web.xml 是部署描述文件
  2. /WEB-INF/classes 用来放置应用程序用到的自定义类(.class),必须包括包(package)结构。
  3. /WEB-INF/lib 用来放置应用程序用到的JAR文件。

6.2 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对象)

6.3 RMI(Remote Method Invocation)

远程方法调用是一种计算机之间利用远程对象互相调用实现双方通讯的一种通讯机制。
使用这种机制,某一台计算机上的对象可以调用另外一台计算机上的对象来获取远程数据。
RMI是Enterprise JavaBeans的支柱,是建立分布式Java应用程序的方便途径。在过去,TCP/IP套接字通讯是远程通讯的主要手段,但此开发方式没有使用面向对象的方式实现开发,在开发一个如此的通讯机制时往往令程序员感觉到乏味,对此RPC(Remote Procedure Call)应运而生,它使程序员更容易地调用远程程序,但在面对复杂的信息传讯时,RPC依然未能很好的支持,而且RPC未能做到面向对象调用的开发模式。针对RPC服务遗留的问题,RMI出现在世人面前,它被设计成一种面向对象的通讯方式,允许程序员使用远程对象来实现通信,并且支持多线程的服务,这是一次远程通讯的***,为远程通信开辟新的里程碑。

RMI的开发步骤

  • 先创建远程接口及声明远程方法,注意这是实现双方通讯的接口,需要继承Remote
  • 开发一个类来实现远程接口及远程方法,值得注意的是实现类需要继承UnicastRemoteObject
  • 通过javac命令编译文件,通过java -server 命令注册服务,启动远程对象
  • 最后客户端查找远程对象,并调用远程方法

6.4Socket创建

  • 服务器端:ServerSocket提供的实例

    ServerSocket server = new ServerSocket(端口号)
    
  • 客户端:Socket提供的实例

    Socket client = new Socket(IP地址,端口号)
    

7.servlet

7.1Servlet体系架构

在这里插入图片描述

  • GenericServlet类:抽象类,定义一个通用的、独立于底层协议的Servlet。
  • 大多数Servlet通过从GenericServlet或HttpServlet类进行扩展来实现
  • ServletConfig接口定义了在Servlet初始化的过程中由Servlet容器传递给Servlet得配置信息对象
  • HttpServletRequest接口扩展ServletRequest接口,为HTTP Servlet提供HTTP请求信息

7.2servlet中init,service,destroy

  • init方法: 是在servlet实例创建时调用的方法用于创建或打开任何与servlet相的资源和初始 化servlet的状态,Servlet规范保证调用init方法前==不会处理任何请求 ==
  • service方法:是servlet真正处理客户端传过来的请求的方法,由web容器调用, 根据HTTP请求方法(GET、POST等),将请求分发到doGet、doPost等方法
  • destory方法:是在servlet实例被销毁时由web容器调用。Servlet规范确保在destroy方法调用之 前所有请求的处理均完成,需要覆盖destroy方法的情况:释放任何在init方法中 打开的与servlet相关的资源存储servlet的状态。destroy()方法仅执行一次,即在服务器停止且卸载Servlet时执行该方法
  • servlet在多线程下其本身并不是线程安全的
    如果在类中定义成员变量,而在service中根据不同的线程对该成员变量进行更改,那么在并发的时候就会引起错误。最好是在方法中,定义局部变量,而不是类变量或者对象的成员变量。由于方法中的局部变量是在栈中,彼此各自都拥有独立的运行空间而不会互相干扰,因此才做到线程安全

7.3Servlet的生命周期

  1. 加载:容器通过类加载器使用Servlet类对应的文件来加载Servlet
  2. 创建:通过调用Servlet的构造函数来创建一个Servlet实例
  3. 初始化:通过调用Servlet的init()方法来完成初始化工作,这个方法是在Servlet已经被创建,但在向客户端提供服务之前调用。
  4. 处理客户请求:Servlet创建后就可以处理请求,当有新的客户端请求时,Web容器都会创建一个新的线程来处理该请求。接着调用Servlet的
    Service()方法来响应客户端请求(Service方***根据请求的method属性来调用doGet()和doPost())
  5. 卸载:容器在卸载Servlet之前需要调用destroy()方法,让Servlet释放其占用的资源。

7.4 Servlet过滤器的配置包括两部分

  1. 第一部分是过滤器在Web应用中的定义,由<filter>元素表示,包括<filter-name><filter-class>两个必需的子元素
  2. 第二部分是过滤器映射的定义,由<filter-mapping>元素表示,可以将一个过滤器映射到一个或者多个Servlet或JSP文件,也可以采用url-pattern将过滤器映射到任意特征的URL。

8.java

8.1Switch

以java8为准,switch支持10种类型
基本类型:byte char short int
包装类 :Byte,Short,Character,Integer String、enum

8.2泛型

8.2.1泛型相关知识

  1. 创建泛型对象的时候一定要指出类型变量T的具体类型。争取让编译器检查出错误,而不是留给JVM运行的时候抛出类不匹配的异常。
  2. JVM如何理解泛型概念 —— 类型擦除。事实上,JVM并不知道泛型,所有的泛型在编译阶段就已经被处理成了普通类和方法。 处理方法很简单,我们叫做类型变量T的擦除(erased) 。
  3. 总结:泛型代码与JVM
    虚拟机中没有泛型,只有普通类和方法
    ② 在编译阶段,所有泛型类的类型参数都会被Object或者它们的限定边界来替换。(类型擦除)
    ③ 在继承泛型类型的时候,桥方法的合成是为了避免类型变量擦除所带来的多态灾难。 无论我们如何定义一个泛型类型,相应的都会有一个原始类型被自动提供。原始类型的名字就是擦除类型参数的泛型类型的名字。

8.2.2使用泛型的好处

  1. 类型安全。
    泛型的主要目标是提高 Java 程序的类型安全。通过知道使用泛型定义的变量的类型限制,编译器可以在一个高得多的程度上验证类型假设。没有泛型,这些假设就只存在于程序员的头脑中(或者如果幸运的话,还存在于代码注释中)。

  2. 消除强制类型转换。
    泛型的一个附带好处是,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

  3. 潜在的性能收益。
    泛型为较大的优化带来可能。在泛型的初始实现中,编译器将强制类型转换(没有泛型的话,程序员会指定这些强制类型转换)插入生成的字节码中。但是更多类型信息可用于编译器这一事实,为未来版本的 JVM 的优化带来可能。由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改。所有工作都在编译器中完成,编译器生成类似于没有泛型(和强制类型转换)时所写的代码,只是更能确保类型安全而已。

所以泛型只是提高了数据传输安全性,并没有改变程序运行的性能

8.3精度丢失

精度丢失只会发生在从大范围到小范围的转换

8.4抽象类

  1. 抽象类不能被实例化,实例化的工作应该交由它的子类来完成,它只需要有一个引用即可。

  2. 抽象方法必须由子类来进行重写。

  3. 只要包含一个抽象方法的类,该类必须要定义成抽象类,不管是否还包含有其他方法。

  4. 抽象类中可以包含具体的方法,当然也可以不包含抽象方法。

  5. abstract不能与final并列修饰同一个类

  6. abstract 不能与private、static、final或native并列修饰同一个方法

  7. 抽象方法只可以被public 和 protected修饰

  8. static final 可以表达在一起来修饰方法,表示是该方法是静态的不可重写的方法

  9. 那么什么叫抽象方法呢?
    在所有的普通方法上面都会有一个{},这个表示方法体,有方法体的方法一定可以被对象直接使用。
    抽象方法,是指没有方法体的方法,同时抽象方法还必须使用关键字abstract做修饰

8.5已知有下列Test类的说明,在该类的main方法的横线处,则下列哪个语句是正确的?

 public class Test
{
	private float f = 1.0f;
	int m = 12;
	static int n = 1;
	public static void main (String args[])
	{
		Test t = new Test();
		————————
	}
} 
  1. f 虽然是 Test 类的私有成员属性,但因为 main 方法就在 Test 类内,因此可以通过 ==“对象名.属性名” ==的方式调用
  2. static 静态成员属性不能使用 this 关键字调用
  3. “类名.” 方式只能调用 静态成员属性

8.6java相关编译命令

  1. javac.exe是编译功能javaCompiler,编译java程序
  2. java.exe是执行程序,用于执行编译好的.class文件
  3. javadoc.exe用来制作java文档
  4. jdb.exe是java的调试器
  5. javaprof.exe是剖析工具
  6. 命令javac- d destination 目的地
  7. 命令javac- s source 起源地
    javac -d 指定放置生成的类文件的位置
    javac -s 指定放置生成的源文件的位置

8.7数组

  • 在java中,数组是一个对象, 不是一种原生类,对象所以存放在堆中,又因为数组特性,是连续的
  • 数组是一个对象,不同类型的数组具有不同的类
  • 数组复制的效率System.arraycopy>clone>Arrays.copyOf>for循环

8.8整数 、小数默认数据类型

  • 整数类型 默认为 int
  • 带小数的默认为 double

8.9"|“与”||"的区别

用法:condition 1 | condition 2condition 1 || condition 2
"|"是按位或:先判断条件1,不管条件1是否可以决定结果(这里决定结果为true),都会执行条件2
"||"是逻辑或:先判断条件1,如果条件1可以决定结果(这里决定结果为true),那么就不会执行条件2

8.10Java体系结构

  1. Java程序设计语言
  2. Java.class文件格式
  3. Java应用编程接口(API)
  4. Java虚拟机

8.11值传递和引用传递参数的调用

  • 值传递是将变量的一个副本传递到方法中,方法中如何操作该变量副本,都不会改变原变量的值
  • 引用传递是将变量的内存地址传递给方法,方法操作变量时会找到保存在该地址的变量,对其进行操作。不能改变实际参数的参考地址,会对原变量造成影响

8.12接口

  • JDK8中,接口中的方法可以被default和static修饰,但被修饰的方法必须有方法体
  • 接口中方法默认被public abstract修饰,抽象方法不可以有方法体

9内部类

内部类(也叫成员内部类)可以有4种访问权限。
在Java中,可以将一个类定义在另一个类里面或者一个方法里边,这样的类称为内部类,广泛意义上的内部类一般包括四种:

  • 成员内部类
  • 局部内部类
  • 匿名内部类
  • 静态内部类 。

9.1成员内部类

(1)该类像是外部类的一个成员,可以无条件的访问外部类的所有成员属性和成员方法(包括private成员和静态成员)

(2)成员内部类拥有与外部类同名的成员变量时,会发生隐藏现象,即默认情况下访问的是成员内部类中的成员。如果要访问外部类中的成员,需要以下形式访问:【外部类.this.成员变量 或 外部类.this.成员方法

(3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问;

(4)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象;

(5)内部类可以拥有private访问权限、protected访问权限、public访问权限及包访问权限。

9.2局部内部类

(1)局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内;

(2)局部内部类就像是方法里面的一个局部变量一样,修饰符abstract、final

9.3匿名内部类

(1)一般使用匿名内部类的方法来编写事件监听代码;

(2)匿名内部类是不能有访问修饰符和static修饰符的

(3)匿名内部类是唯一一种没有构造器的类;

(4)匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

9.4内部静态类

(1)静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似;

(2)不能使用外部类的非static成员变量或者方法。
(3)static关键词修饰的变量或方法可以通过类名直接调用,而非静态的变量或方法无法通过类名直接调用

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值