一.JavaSE、Socket
1、实现事件监听的四种方式:
本类继承接口、外部类实现、内部类实现、内部匿名类实现。
2、socket的accept()方法会阻塞线程,注意该方法调用的位置和时机,防止程序阻塞遇到意想不到的效果
3、笔试小记:String aa=123 Stringaa=123.toString Stringaa=(String)123都不对.String aa;Double a=123;aa=a;正确
4、Swing编程:打开、新建、保存文件
JFileChooser JFileChooser为用户选择文件提供了一种简单的机制。
intshowDialog(Component parent, String approveButtonText)
弹出具有自定义approve按钮的自定义文件选择器对话框。
intshowOpenDialog(Component parent)
弹出一个"Open File"文件选择器对话框。
intshowSaveDialog(Component parent)
弹出一个"Save File"文件选择器对话框。
voidsetFileFilter(FileFilter filter)
设置当前文件过滤器。
还有一种专用的文件对话框FileDialog,也可处理文件的打开保存新建等。
5、NULL代表声明了一个空对象,根本就不是一个字符串。
""代表声明了一个对象实例,这个对象实例的值是一个长度为0的空字符串。
NULL代表声明了一个空对象,对空对象做任何操作都不行的,除了=和==
""是一个字符串了,只是这个字符串里面没有内容了
Strings=null;只是定义了一个句柄,也就是说你有了个引用,但是这个引用未指向任何内存空间
Strings="";这个引用已经指向了一块是空字符串的内存空间,是一个实际的东东了,所以你可以对它操作,而不用担心什么了
6、一个可以选择图像的功能代码,且可设置图像大小。
JFileChooser chooser=newJFileChooser("F:/文件/本学期相关课件/Java高级应用代码/MyChatRoomProgram/MyChatRoom");
//设置过滤条件
FileNameExtensionFilter filter=newFileNameExtensionFilter("图片文件——jpg","jpg");
//获取当前文件目录
File file=chooser.getCurrentDirectory();
//设置当前文件目录
chooser.setCurrentDirectory(file);
//设置过滤器
chooser.setFileFilter(filter);
int i=chooser.showDialog(this,"选择");
if(i==JFileChooser.APPROVE_OPTION)
{
imgPath=chooser.getSelectedFile().getAbsolutePath();
//创建ImageIcon对象
ImageIconimg=new ImageIcon(imgPath);
//创建Image对象,ImageIcon的getImage()方法返回该类型对象
ImagesourceImg=img.getImage();
//该方法用来缩放图像、
ImagescaleImg=sourceImg.getScaledInstance(200,250,Image.SCALE_DEFAULT);
//setIcon(Icon icon)
imgLabel1.setIcon(new ImageIcon(scaleImg));
……(仅给出关键代码)
7、内部类与匿名类相关
内部类可以访问任何外部类的成员,外部类要通过创建内部类的对象来访问内部类的成员,且可访问任何内部类成员。在外部类之外创建内部类对象时,需要用
<外部类名>.<内部类名> 引用名=<外部类对象的引用>.new<内部类的构造方法>
来声明
当内外部类成员重名时,单用this是区别不开的,在内部类中访问外部类的成员时可用<外部类名>.this.<外部类中被访问的成员>区分。
局部内部类可访问外部类的所有成员,但不可访问在同一个局部块的普通局部变量,此局部变量需要是final的,因为普通变量在代码结束后就消亡,而局部类对象和final变量会一直存在。
8、equals和“==”的关系
equals继承自Object基类,==是运算符。如果比较基本类型,则用==比较,不能用equals。在Object中,equals判断就是==判断。附上源码:
public boolean equals(Object obj) {
return (this == obj);
}
==在比较引用和基本类型是具有不同的功能。在比较基本类型时,若值相同,则返回true,比较引用时,若引用指向内存中的同一对象,则返回true,即比较引用的地址值(地址在栈中)。其实二者的实质是一样的,都是比较栈中某一块内存区域存储的值是否相同,只不过对于基本类型来说,栈区存储的值就是基本类型的值,而对于引用类型来说,栈区的值存放的是该引用指向的对象的堆内存值或者说值的映射,所以当两个对象是同一个对象时,其栈区存储的引用的值是相同的。
但是在String类中比较特殊,因为String重写了equals方法,使得两个String对象A和B在equals返回true的条件是:A和B是同一个String对象,或者A与B虽然不是同一个对象,但他们的串值相同。
如:String s1=”abc”;Strings2=”abc”,则s1==s2返回true,因为他们是同一个对象,地址相同;s1.equals(s2)也返回true,因为他们的内容也相同。
又如:String s1=”abc”;Strings2=new String(“abc”);则s1==s2返回false,s1.equals(s2)返回true,因为他们不是同一个对象,地址不同,但是内容相同。
这里介绍一下字符串缓冲池的概念:在内存中有字符串缓冲池,在声明一个引用时,现在缓冲池中寻找对应的对象,若找到了,则指向这个对象,若找不到,则创建一个新的,如第一个例子,在声明s2时,实际上指向的还是前一个s1指向的对象。但第二个例子用newString(),这是显示的要求重新创建一个新的对象,程序将不再在缓冲池中寻找,而是直接创建一个新的对象。
简单的来将,==比较的是值,这里要注意一个概念,引用类型的值指的是地址,equals在没有重写的情况下,比较的也是栈中的地址值,但一般会在我们的扩展类中重写,如String,从而比较的是对象的内容。但注意重写equals的同时也要重写hashCode方法。
9、重写equals方法注意事项
我们知道重写equals方法的几大原则:
1. 自反性:对于任意的引用值x,x.equals(x)一定为true。
2. 对称性:对于任意的引用值x 和y,当x.equals(y)返回true时,
y.equals(x)也一定返回true。
3. 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,
并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
4. 一致性:对于任意的引用值x 和y,如果用于equals比较的对象信息没有被修
改,多次调用x.equals(y)要么一致地返回true,要么一致地返回false。
5. 非空性:对于任意的非空引用值x,x.equals(null)一定返回false。
6.重写equals方法一般也要重写hashCode方法。
(转)如何理解hashCode的作用:
============================================================
以java.lang.Object来理解,JVM每new一个Object,它都会将这个Object丢到一个Hash哈希表中去,这样的话,下次做Object的比较或者取这个对象的时候,它会根据对象的hashcode再从Hash表中取这个对象。这样做的目的是提高取对象的效率。具体过程是这 样:
1.new Object(),JVM根据这个对象的Hashcode值,放入到对应的Hash表对应的Key上,如果不同的对象确产生了相同的hash值,也就是发 生了Hashkey相同导致冲突的情况,那么就在这个Hashkey的地方产生一个链表,将所有产生相同hashcode的对象放到这个单链表上去,串在一起。
2.比较两个对象的时候,首先根据他们的hashcode去hash表中找他的对象,当两个对象的hashcode相同,那么就是说他们这两个对象放在Hash表中的同一个key上,那么他们一 定在这个key上的链表上。那么此时就只能根据Object的equal方法来比较这个对象是否equal。当两个对象的hashcode不同的话,肯定 他们不能equal.
============================================================
改写equals时总是要改写hashCode
============================================================
java.lang.Object中对hashCode的约定:
1.在一个应用程序执行期间,如果一个对象的equals方法做比较所用到的信息没有被修改的话,则对该对象调用hashCode方法多次,它必须始终如一地返回同一个整数。
2.如果两个对象根据equals(Objecto)方法是相等的,则调用这两个对象中任一对象的hashCode方法必须产生相同的整数结果。
3.如果两个对象根据equals(Objecto)方法是不相等的,则调用这两个对象中任一个对象的hashCode方法,不要求产生不同的整数结果。但如果能不同,则可能提高散列表的性能。
有一个概念要牢记,两个相等对象的equals方法一定为true, 但两个hashcode相等的对象不一定是相等的对象。
所以hashcode相等只能保证两个对象在一个HASH表里的同一条HASH链上,继而通过equals方法才能确定是不是同一对象,如果结果为true, 则认为是同一对象在插入,否则认为是不同对象继续插入。
10、关于java使用IO流读取资源文件时的问题
有时候我们写程序时可能需要读取一个excel文件,或者打开一张图片,在程序中往往有很多方式可以读取,如直接new File()括号里面写路径啊等,或者采用
URL url =getClass().getResource("/resource/" + fileName); InputStream is =url.openStream();
获得输入流,这样都是可以的,但是我们可能偶尔会发现一个问题,就是用以上的方式在源程序里可以正确的运行,但是打包之后,打成可执行的jar包之后,去运行jar包时,往往报错,找不到资源文件!仔细查看,发现资源文件也加载进jar包了啊,但是就是读取不了。这里提供一个很好的方式:
如打开excel文件:
InputStreamis=this.getClass().getResourceAsStream("/resource/" +fileName);
Workbook rwb =Workbook.getWorkbook(is);
又如打开图片文件:
InputStream imbb = getClass()
.getResourceAsStream("/images/bb.jpg");
InputStream imaa = getClass()
.getResourceAsStream("/images/aa.jpg");
BufferedImage srcImageB = null;
BufferedImage srcImageA = null;
try {
srcImageB = ImageIO.read(imbb);
srcImageA = ImageIO.read(imaa);
}catch (IOException e1) {
e1.printStackTrace();
}
这样用流的方式打开/读取资源文件,打成jar包之后也可以正确执行了。
以下是几种filePath读法:
二、JavaEE
1、Tomcat+Mysql配置数据源:
(1)需要一个context.xml.文件,里面的内容一般为:
<?xml version="1.0"encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/DbPool" 数据源名称
auth="Container" 由容器创建和管理Resource
type="javax.sql.DataSource" 数据源类型
username="root" MySql数据库用户名
password="root" MySql数据库密码
maxIdle="30" 最大数据库空闲连接数量
maxActive="100" 最大数据库活跃连接数量
maxWait="5000" 最大数据库等待连接数量
driverClassName="com.mysql.jdbc.Driver" Mysql数据库连接驱动
url="jdbc:mysql://localhost:3309/user"/> 连接数据库德Url地址
</Context>
(2)将MySql数据库连接工具包加入到tomcat的lib文件夹下
(3)编写连接数据源类文件,其主要代码如下:
import java.sql.Connection;
importjava.sql.ResultSet;
importjava.sql.SQLException;
importjava.sql.Statement;
importjavax.sql.DataSource;
importjavax.naming.*;
importjavax.naming.Context;
importjavax.naming.NamingException;
publicclass DbPool {
private Connection conn;
public void createConn()
{
try{
Context initCtx=newjavax.naming.InitialContext();
Context envCtx=(Context)initCtx.lookup("java:comp/env");
DataSource ds=(DataSource)envCtx.lookup("jdbc/DbPool");
conn=ds.getConnection();
System.out.println("数据库连接成功!");
}catch(Exception e){
System.out.println("数据库连接失败");
e.printStackTrace();
}
}
}
(4)至此,数据源就配置好了,要用到数据库连接时,只需实例化该类即可。
2、Servlet的生命周期
1、Web Client向容器发出请求
2、servlet容器接受到请求
3、容器创建一个HttpRequest对象,将Web client请求信息封装
4、Servlet创建一个HttpResponse对象
5、从请求的URL中找到正确的servlet,容器为其创建/分配一个线程,servlet加载,实例化(有些servlet在容器启动时就已经加载完成了,,只需要找到正确的就行了,然后创建一个config对象用来实例化)
6、调用inti()方法,接着调用service()方法。
7、调用destroy()方法
8,销毁该servlet实例
注:1、如果在某个servlet中未覆盖/重写service方法,则HttpServlet中的service()方法会根据客户端的post或get调用相应的doPost()或者doGet()方法,此时应重写doXX()方法。
2、若重写了service()方法,则此service既可以处理post也可以处理get,不会再调用其父类中的doXX()方法,除非在service()末尾又加上super.service();
3、最好不要在servlet中定义成员变量,至少用户专有的数据不要定义成成员变量。因为一般用户请求会调用同一个service()方法。