一、 java Cloneable 详解 (clone,克隆)
上面是GOF设计模式中对原型模式的图形结构描述,原型模式通过克隆使我们可以得到一个对象的复制版本.其好处就是让我们在需要一个与现有对象类似的实例时,不用一一进行每个成员的赋值,而是直接通过现有的对象复制.并且复制出来的对象是互相独立的.
如上图,当对象进行了这样的赋值以后,两个变量指向了同一个对象实例,也就是说它们都引用是相同的,在这种情况下,其中一个对象的改变都会影响另一个对象的变化.两个对象互不独立.
如果想得到互相独立的两个对象就要使用Clone方法,如上图,经Clone后,任何一个对象的改变都不会影响另一个对象。Object1上Object2是两个不同的引用.
如果一个欲实现 Clone 方法的对象其成员中还包含其它对象 ,那么那些对象同样要实现Clone方法(也就是说,同样要实现 Cloneable 接口) ,而且在上一层的对象中要调用这些 Clone 方法.以此类推,直到最后一个对象中没有对象值为止(深拷贝) .
在JAVA中,要实现 Clone方法就要实现 Cloneable 接口,但是 Clone 方法不是这个接口的方法,它只是一个标识接口 。Clone 方法是从 Object 对象继承下来的protected方法,在实现它的时候要声明为public 。在使用Clone的时候还要记得进行类型转换,因为Clone 方法返回的是一个Object 。
下面是一小段简单的代码,是对对象克隆的实验:
package js; /** * ImplClone * @author jiashuai * */ public class ImplClone implements Cloneable { private String name = ""; private Birth birth; /** Creates a new instance of ImplClone */ public ImplClone() { this.setName("bill"); this.birth = new Birth(); } public Object clone() { ImplClone cloned = new ImplClone(); try { cloned = (ImplClone) super.clone(); cloned.birth = (Birth) this.birth.clone(); } catch (CloneNotSupportedException ex) { ex.printStackTrace(); } //cloned.birth = (Birth) birth.clone(); return cloned; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Birth getBirth() { return birth; } public void setBirth(Birth birth) { this.birth = birth; } } /** * Birth * @author jiashuai * */ class Birth implements Cloneable { private String year; private String month; private String day; public Birth(String year, String month, String day) { this.year = year; this.month = month; this.day = day; } public Birth() { } public String getYear() { return year; } public void setYear(String year) { this.year = year; } public String getMonth() { return month; } public void setMonth(String month) { this.month = month; } public String getDay() { return day; } public void setDay(String day) { this.day = day; } public Object clone() { Birth cloned = new Birth(); try { cloned = (Birth) super.clone(); } catch (CloneNotSupportedException ex) { ex.printStackTrace(); } return cloned; } }
package js; /** * CloneMain * @author jiashuai * */ public class CloneMain { /** Creates a new instance of CloneMain */ public CloneMain() { } public static void main(String[] args){ ImplClone cloneObj=new ImplClone(); cloneObj.setName("Bill"); cloneObj.setBirth(new Birth("2004","03","01")); System.out.println(cloneObj.getBirth().getYear()+" :1"); //ImplClone cloned=new ImplClone(); //cloned=cloneObj; ImplClone cloned=(ImplClone)cloneObj.clone(); cloned.getBirth().setYear("1990"); //改变克隆对象的数据 System.out.println(cloneObj.getBirth().getYear()+" :2"); //输出原对象 System.out.println(cloned.getBirth().getYear()+" :3"); //输出改变数据后的克隆对象 } }
二、 用字节(byte) 截取字符串的问题
( 用字节(byte) 截取字符串的问题 )
编写一个截取字符串的函数,输入为一个字符串和字节数,输出为按字节截取的字符串。 但是要保证汉字不被截半个,如“我ABC”4,应该截为“我AB”,输入“我ABC汉DEF”,6,应该输出为“我ABC”而不是“我ABC+汉的半个”。
import java.io.UnsupportedEncodingException; public class TestSubString { /** * 变成 byte[] 截取,然后在转换成一个新的 String 如果旧的 String 包含 新的 String * 说明没有截取到半个汉字,如果不包含说明截取到半个汉字了, * 那么就少截取一个字符来防止半个字符存在 * @param str * @param sub * @return * @throws UnsupportedEncodingException */ public String test(String str,int sub) throws UnsupportedEncodingException{ String retVal = ""; if (str == null || str.equals("") || sub == 0) { return retVal; } byte[] b = str.getBytes("GBK"); if (b.length < sub) { return str; } byte[] temp = new byte[sub]; for (int i = 0; i < sub; i++) { temp[i] = b[i]; } String tempStr = new String(temp); if (str.contains(tempStr)) { return tempStr; } temp = new byte[sub-1]; for (int i = 0; i < sub-1; i++) { temp[i] = b[i]; } retVal = new String(temp); return retVal; } /** * 打印字符串在指定编码下的字节数和编码名称到控制台 * * @param s * 字符串 * @param encodingName * 编码格式 */ public void printByteLength(String s, String encodingName) { System.out.print("字节数:"); try { System.out.print(s.getBytes(encodingName).length); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } System.out.println(";编码:" + encodingName); } public static void main(String[] args) throws UnsupportedEncodingException { TestSubString tss = new TestSubString(); String en = "A"; String ch = "人"; // 计算一个英文字母在各种编码下的字节数 System.out.println("英文字母:" + en); tss.printByteLength(en, "GB2312"); tss.printByteLength(en, "GBK"); tss.printByteLength(en, "GB18030"); tss.printByteLength(en, "ISO-8859-1"); tss.printByteLength(en, "UTF-8"); tss.printByteLength(en, "UTF-16"); tss.printByteLength(en, "UTF-16BE"); tss.printByteLength(en, "UTF-16LE"); System.out.println(); // 计算一个中文汉字在各种编码下的字节数 System.out.println("中文汉字:" + ch); tss.printByteLength(ch, "GB2312"); tss.printByteLength(ch, "GBK"); tss.printByteLength(ch, "GB18030"); tss.printByteLength(ch, "ISO-8859-1"); tss.printByteLength(ch, "UTF-8"); tss.printByteLength(ch, "UTF-16"); tss.printByteLength(ch, "UTF-16BE"); tss.printByteLength(ch, "UTF-16LE"); //------------------------------------------------------------------------------- System.out.println(); String t1 = "我ABC汉DEF"; System.out.println(tss.test(t1, 4)); System.out.println(tss.test(t1, 6)); } }
运行结果:
英文字母:A
字节数:1;编码:GB2312
字节数:1;编码:GBK
字节数:1;编码:GB18030
字节数:1;编码:ISO-8859-1
字节数:1;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE
中文汉字:人
字节数:2;编码:GB2312
字节数:2;编码:GBK
字节数:2;编码:GB18030
字节数:1;编码:ISO-8859-1
字节数:3;编码:UTF-8
字节数:4;编码:UTF-16
字节数:2;编码:UTF-16BE
字节数:2;编码:UTF-16LE
我AB
我ABC
--------------------------------
可知,GB2312、GBK、GB18030 三种编码格式都符合题目要求
注意 .java 文件也要是相同编码,否则控制台显示乱码
三、 Java URL 工具类(解决 url 和 java 之间的乱码问题)
Java URL 工具类
package ssh.util; import java.io.BufferedReader; import java.io.InputStreamReader; import java.io.UnsupportedEncodingException; import java.net.HttpURLConnection; import java.net.URL; import java.net.URLConnection; import java.net.URLDecoder; import java.net.URLEncoder; import java.util.Iterator; import java.util.Map; import javax.servlet.http.HttpServletRequest; /** * URL工具 * @author gary * */ public class URLUtil { /** * 对url进行编码 */ public static String encodeURL(String url) { try { return URLEncoder.encode(url, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } /** * 对url进行解码 * @param url * @return */ public static String decodeURL(String url){ try { return URLDecoder.decode(url, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); return null; } } /** * 判断URL地址是否存在 * @param url * @return */ public static boolean isURLExist(String url) { try { URL u = new URL(url); HttpURLConnection urlconn = (HttpURLConnection) u.openConnection(); int state = urlconn.getResponseCode(); if (state == 200) { return true; } else { return false; } } catch (Exception e) { return false; } } /** * 将请求参数还原为key=value的形式,for struts2 * @param params * @return */ public static String getParamString(Map<?, ?> params) { StringBuffer queryString = new StringBuffer(256); Iterator<?> it = params.keySet().iterator(); int count = 0; while (it.hasNext()) { String key = (String) it.next(); String[] param = (String[]) params.get(key); for (int i = 0; i < param.length; i++) { if (count == 0) { count++; } else { queryString.append("&"); } queryString.append(key); queryString.append("="); try { queryString.append(URLEncoder.encode((String) param[i], "UTF-8")); } catch (UnsupportedEncodingException e) { } } } return queryString.toString(); } /** * 获得请求的路径及参数 * @param request * @return */ public static String getRequestURL(HttpServletRequest request) { StringBuffer originalURL = new StringBuffer(request.getServletPath()); Map<?,?> parameters = request.getParameterMap(); if (parameters != null && parameters.size() > 0) { originalURL.append("?"); originalURL.append(getParamString(parameters)); } return originalURL.toString(); } /** * 抓取网页内容,自动识别编码 * @param urlString * @return */ public static String url2Str(String urlString) { try { StringBuffer html = new StringBuffer(); URL url = new URL(urlString); HttpURLConnection conn = (HttpURLConnection) url.openConnection(); URLConnection c = url.openConnection(); c.connect(); String contentType = c.getContentType(); String characterEncoding = null; int index = contentType.indexOf("charset="); if(index == -1){ characterEncoding = "UTF-8"; }else{ characterEncoding = contentType.substring(index + 8, contentType.length()); } InputStreamReader isr = new InputStreamReader(conn.getInputStream(), characterEncoding); BufferedReader br = new BufferedReader(isr); String temp; while ((temp = br.readLine()) != null) { html.append(temp).append("\n"); } br.close(); isr.close(); return html.toString(); } catch (Exception e) { e.printStackTrace(); return null; } } public static void main(String[] args) { String content = URLUtil.url2Str("http://www.baidu.com");; System.out.println(content); } }
JS 中 编码解码
encodeURI(URI) decodeURI(encodedURI);
四、 Java HTML 工具类
Java HTML 工具类
package ssh.util; import java.util.regex.Matcher; import java.util.regex.Pattern; /** * HTML工具 * @author gary * */ public class HTMLUtil { //> public static final String GT = ">"; //< public static final String LT = "<"; //" public static final String QUOT = """; //& public static final String AMP = "&"; //空格 public static final String SPACE = " "; //© public static final String COPYRIGHT = "©"; //® public static final String REG = "®"; //™ public static final String TM = "™"; //¥ public static final String RMB = "¥"; /** * 删除script标签 * @param str * @return */ public static String delScriptTag(String str){ String regEx_script = "<script[^>]*?>[\\s\\S]*?<\\/script>"; Pattern p_script = Pattern.compile(regEx_script,Pattern.CASE_INSENSITIVE); Matcher m_script = p_script.matcher(str); str = m_script.replaceAll(""); return str.trim(); } /** * 删除style标签 * @param str * @return */ public static String delStyleTag(String str){ String regEx_style="<style[^>]*?>[\\s\\S]*?<\\/style>"; Pattern p_style = Pattern.compile(regEx_style,Pattern.CASE_INSENSITIVE); Matcher m_style = p_style.matcher(str); str = m_style.replaceAll(""); return str; } /** * 删除HTML标签 * @param str * @return */ public static String delHTMLTag(String str){ String regEx_html = "<[^>]+>"; Pattern p_html = Pattern.compile(regEx_html,Pattern.CASE_INSENSITIVE); Matcher m_html = p_html.matcher(str); str = m_html.replaceAll(""); return str; } /** * 删除所有标签 * @param str * @return */ public static String delAllTag(String str){ //删script str = delScriptTag(str); //删style str = delStyleTag(str); //删HTML str = delHTMLTag(str); return str; } /** * 清除标签,恢复HTML转义字符 * @param str * @return */ public static String clean(String str){ str = delAllTag(str); str = str.replaceAll(SPACE, " "); str = str.replaceAll(GT, ">"); str = str.replaceAll(LT, "<"); str = str.replaceAll(QUOT, "\""); str = str.replaceAll(AMP, "&"); str = str.replaceAll(COPYRIGHT, "©"); str = str.replaceAll(REG,"®"); str = str.replaceAll(TM,"™"); str = str.replaceAll(RMB,"¥"); return str; } /** * 过滤指定标签 * @param str * @param tag * 指定标签 * @return String */ public static String fiterHtmlTag(String str, String tag) { String regxp = "<\\s*" + tag + "\\s+([^>]*)\\s*>"; Pattern pattern = Pattern.compile(regxp); Matcher matcher = pattern.matcher(str); StringBuffer sb = new StringBuffer(); boolean result1 = matcher.find(); while (result1) { matcher.appendReplacement(sb, ""); result1 = matcher.find(); } matcher.appendTail(sb); return sb.toString(); } /** * 替换指定的标签 * @param str * @param beforeTag * 要替换的标签 * @param tagAttrib * 要替换的标签属性值 * @param startTag * 新标签开始标记 * @param endTag * 新标签结束标记 * @return String * example: 替换img标签的src属性值为[img]属性值[/img] */ public static String replaceHtmlTag(String str, String beforeTag, String tagAttrib, String startTag, String endTag) { String regxpForTag = "<\\s*" + beforeTag + "\\s+([^>]*)\\s*>"; String regxpForTagAttrib = tagAttrib + "=\"([^\"]+)\""; Pattern patternForTag = Pattern.compile(regxpForTag); Pattern patternForAttrib = Pattern.compile(regxpForTagAttrib); Matcher matcherForTag = patternForTag.matcher(str); StringBuffer sb = new StringBuffer(); boolean result = matcherForTag.find(); while (result) { StringBuffer sbreplace = new StringBuffer(); Matcher matcherForAttrib = patternForAttrib.matcher(matcherForTag .group(1)); if (matcherForAttrib.find()) { matcherForAttrib.appendReplacement(sbreplace, startTag + matcherForAttrib.group(1) + endTag); } matcherForTag.appendReplacement(sb, sbreplace.toString()); result = matcherForTag.find(); } matcherForTag.appendTail(sb); return sb.toString(); } public static void main(String[] args) { System.out.println(clean(URLUtil.url2Str("http://www.baidu.com"))); } }
五、 用 Java 判断一个URL是否有效
针对一些 URL 地址进行检测是否可用,使用 java.net 下的类来实现,主要用到了 URL 和 HttpURLConnection 二个类 , URL 是统一资源标识符的引用,一个 URL 实例代表着一个 url 的引用,开始使用了 URL 中的的 openStream() 方法,这样使用倒是可以,但是速度慢,代码如下:
try { url = new URL("http://127.0.0.1/sj/user/getUser"); in = url.openStream(); } catch (Exception e1) { System.out.println("连接打不开!"); url = null; }
下面判断 url 是不是 null 就可以了,速度慢
最后使用了HttpURLConnection 中的 getResponseCode() ;方法,HttpURLConnection : 通常一个HttpURLConnection 的实例可以生成一个请求,它有个方法 getResponseCode() ;可以得到请求的响应状态,该方法返回一个 int 分别是 200 and 404 如无法从响应中识别任何代码则返回 -1 ,代码如下:
import java.net.HttpURLConnection; import java.net.URL; public class URLAvailability { private static URL url; private static HttpURLConnection con; private static int state = -1; /** * 功能:检测当前URL是否可连接或是否有效, 描述:最多连接网络 5 次, 如果 5 次都不成功,视为该地址不可用 * * @param urlStr 指定URL网络地址 * @return URL */ public synchronized URL isConnect(String urlStr) { int counts = 0; if (urlStr == null || urlStr.length() <= 0) { return null; } while (counts < 5) { try { url = new URL(urlStr); con = (HttpURLConnection) url.openConnection(); state = con.getResponseCode(); System.out.println(counts + "= " + state); if (state == 200) { System.out.println("URL可用!"); } break; } catch (Exception ex) { counts++; System.out.println("URL不可用,连接第 " + counts + " 次"); urlStr = null; continue; } } return url; } }
六、 Java 对象序列化
java对象序列化
所谓对象序列化就是将对象的状态转换成字节流,以后可以通过这些值再生成相同状态的对象。这个过程也可以通过网络实现,可以先在Windows机器上创建一个对象,对其序列化,然后通过网络发给一台Unix机器,然后在那里准确无误地重新"装配"。像RMI、Socket、JMS、EJB它们中的一种,彼此为什么能够传递Java对象,当然都是对象序列化机制的功劳。
java对象序列化机制一般来讲有两种用途:
1. Java的JavaBeans: Bean的状态信息通常是在设计时配置的,Bean的状态信息必须被存起来,以便当程序运行时能恢复这些状态信息,这需要将对象的状态保存到文件中,而后能够通过读入对象状态来重新构造对象,恢复程序状态。
2. RMI允许象在本机上一样操作远程机器上的对象;或使用套接字在网络上传送对象的程序来说,这些都是需要实现serializaiton机制的。
我们通过让类实现java.io.Serializable 接口可以将类序列化。这个接口是一个制造者(marker)接口。也就是说,对于要实现它的类来说,该接口不需要实现任何方法。它主要用来通知Java虚拟机(JVM),需要将一个对象序列化。
对于这个,有几点我们需要明确:
(1). 并非所有类都可以序列化,在cmd下,我们输入serialver java.net.Socket,可以得到socket是否可序列化的信息,实际上socket是不可序列化的。
(2). java有很多基础类已经实现了serializable接口,比如string,vector等。但是比如hashtable就没有实现serializable接口。
将对象读出或者写入流的主要类有两个: ObjectOutputStream与ObjectInputStream 。ObjectOutputStream 提供用来将对象写入输出流的writeObject方法, ObjectInputStream提供从输入流中读出对象的readObject方法。使用这些方法的对象必须已经被序列化的。也就是说,必须已经实现 Serializable接口。如果你想writeobject一个hashtable对象,那么,会得到一个异常。
序列化的过程就是对象写入字节流和从字节流中读取对象。将对象状态转换成字节流之后,可以用java.io包中的各种字节流类将其保存到文件中,管道到另一线程中或通过网络连接将对象数据发送到另一主机。对象序列化功能非常简单、强大,在RMI、Socket、JMS、EJB都有应用。对象序列化问题在网络编程中并不是最激动人心的课题,但却相当重要,具有许多实用意义。
1. 对象序列化可以实现分布式对象。主要应用例如:RMI要利用对象序列化运行远程主机上的服务,就像在本地机上运行对象时一样。
2. java对象序列化不仅保留一个对象的数据,而且递归保存对象引用的每个对象的数据。可以将整个对象层次写入字节流中,可以保存在文件中或在网络连接上传递。利用对象序列化可以进行对象的“深复制”,即复制对象本身及引用的对象本身。序列化一个对象可能得到整个对象序列。
java序列化比较简单,通常不需要编写保存和恢复对象状态的定制代码。实现java.io.Serializable接口的类对象可以转换成字节流或从字节流恢复,不需要在类中增加任何代码。只有极少数情况下才需要定制代码保存或恢复对象状态。这里要注意:不是每个类都可序列化,有些类是不能序列化的,例如涉及线程的类与特定JVM有非常复杂的关系。
序列化机制:
序列化分为两大部分:序列化 和反序列化 。序列化是这个过程的第一部分,将数据分解成字节流,以便存储在文件中或在网络上传输。反序列化就是打开字节流并重构对象。对象序列化不仅要将基本数据类型转换成字节表示,有时还要恢复数据。恢复数据要求有恢复数据的对象实例。ObjectOutputStream中的序列化过程与字节流连接,包括对象类型和版本信息。反序列化时,JVM用头信息生成对象实例,然后将对象字节流中的数据复制到对象数据成员中。下面我们分两大部分来阐述:
处理对象流:
(序列化过程和反序列化过程)
java.io包有两个序列化对象的类。ObjectOutputStream负责将对象写入字节流,ObjectInputStream从字节流重构对象。
我们先了解ObjectOutputStream类吧。ObjectOutputStream类扩展DataOutput接口。
writeObject() 方法是最重要的方法,用于对象序列化。如果对象包含其他对象的引用,则writeObject()方法递归序列化这些对象。每个 ObjectOutputStream维护序列化的对象引用表,防止发送同一对象的多个拷贝。(这点很重要)由于writeObject()可以序列化整组交叉引用的对象,因此同一ObjectOutputStream实例可能不小心被请求序列化同一对象。这时,进行反引用序列化,而不是再次写入对象字节流。
下面,让我们从例子中来了解ObjectOutputStream这个类吧。
// 序列化 today's date 到一个文件中. FileOutputStream f = new FileOutputStream ("tmp" ); ObjectOutputStream s = new ObjectOutputStream (f); s.writeObject("Today" ); s.writeObject(new Date ()); s.flush();
现在,让我们来了解ObjectInputStream这个类。它与ObjectOutputStream相似。它扩展DataInput接口。 ObjectInputStream中的方法镜像DataInputStream中读取Java基本数据类型的公开方法。readObject()方法从字节流中反序列化对象。每次调用readObject()方法都返回流中下一个Object。对象字节流并不传输类的字节码,而是包括类名及其签名。 readObject()收到对象时,JVM装入头中指定的类。如果找不到这个类,则readObject()抛出 ClassNotFoundException,如果需要传输对象数据和字节码,则可以用RMI框架。ObjectInputStream的其余方法用于定制反序列化过程。
例子如下:
//从文件中反序列化 string 对象和 date 对象 FileInputStream in = new FileInputStream ("tmp" ); ObjectInputStream s = new ObjectInputStream (in); String today = (String )s.readObject(); Date date = (Date )s.readObject();
定制序列化过程:
序列化通常可以自动完成,但有时可能要对这个过程进行控制。java可以将类声明为serializable,但仍可手工控制声明为static或transient的数据成员。
例子:一个非常简单的序列化类。
public class simpleSerializableClass implements Serializable { String sToday="Today:" ; transient Date dtToday=new Date (); }
序列化时,类的所有数据成员应可序列化除了声明为transient 或static的成员。将变量声明为transient告诉JVM我们会负责将变元序列化。将数据成员声明为transient后,序列化过程就无法将其加进对象字节流中,没有从transient数据成员发送的数据。后面数据反序列化时,要重建数据成员(因为它是类定义的一部分),但不包含任何数据,因为这个数据成员不向流中写入任何数据。记住,对象流不序列化static或transient。我们的类要用writeObject()与 readObject()方法以处理这些数据成员。使用writeObject()与readObject()方法时,还要注意按写入的顺序读取这些数据成员。
关于如何使用定制序列化的部分代码如下:
//重写writeObject()方法以便处理transient的成员。 public void writeObject(ObjectOutputStream outputStream) throws IOException { outputStream.defaultWriteObject();//使定制的writeObject()方法可以 利用自动序列化中内置的逻辑。 outputStream.writeObject(oSocket.getInetAddress()); outputStream.writeInt(oSocket.getPort()); } //重写readObject()方法以便接收transient的成员。 private void readObject(ObjectInputStream inputStream) throws IOException ,ClassNotFoundException { inputStream.defaultReadObject();//defaultReadObject()补充自动序列化 InetAddress oAddress=(InetAddress )inputStream.readObject(); int iPort =inputStream.readInt(); oSocket = new Socket (oAddress,iPort); iID=getID(); dtToday =new Date (); }
完全定制序列化过程:
如果一个类要完全负责自己的序列化,则实现Externalizable接口而不是Serializable接口。Externalizable接口定义包括两个方法writeExternal()与readExternal()。利用这些方法可以控制对象数据成员如何写入字节流.类实现 Externalizable时,头写入对象流中,然后类完全负责序列化和恢复数据成员,除了头以外,根本没有自动序列化。这里要注意了。声明类实现 Externalizable接口会有重大的安全风险。writeExternal()与readExternal()方法声明为public,恶意类可以用这些方法读取和写入对象数据。如果对象包含敏感信息,则要格外小心。这包括使用安全套接或加密整个字节流。到此为至,我们学习了序列化的基础部分知识。
相关推荐
Java哲学家就餐问题是一个经典的多线程同步问题,源自计算机科学家Dijkstra提出的一个思想实验。在该问题中,五个哲学家围坐在一张圆桌旁,每人面前有一根筷子。他们交替进行思考和吃饭,但必须拿到左右两边的两根...
Tcp服务端与客户端的JAVA实例源代码,一个简单的Java TCP服务器端程序,别外还有一个客户端的程序,两者互相配合可以开发出超多的网络程序,这是最基础的部分。 递归遍历矩阵 1个目标文件,简单! 多人聊天室 3...
java中一对一的聊天代码,运用了相关的技术实现,QQ聊天代码不过如此!
车辆路径问题(Vehicle Routing Problem, VRP)是一个经典的优化问题,它在物流、运输和配送等领域广泛应用。在VRP中,我们需要找到一个最优的车辆路线集合,使得一组车辆能够从一个中央仓库出发,访问一系列客户点...
JAVA面试问题总结 JAVA是一种广泛应用的编程语言,作为一名JAVA开发者,需要具备扎实的基础知识和实践经验。本文总结了常见的JAVA面试问题,涵盖了JAVA基础、JSP、Servlet、XML、J2EE、MVC、数据库等方面的知识点。...
总的来说,这份“Java相关文档”对于想深入理解Java多线程编程的开发者来说是一份宝贵的资源,它涵盖了从基础知识到高级特性的全面内容,可以帮助开发者更好地利用Java进行并发编程,提升程序性能,解决并发问题。...
java.awt.dnd Drag 和 Drop 是一种直接操作动作,在许多图形用户界面系统中都会遇到它,它提供了一种机制,能够在两个与 GUI 中显示元素逻辑相关的实体之间传输信息。 java.awt.event 提供处理由 AWT 组件所激发的...
Java相关课程系列笔记之八JavaScript学习笔记(建议用WPS打开) Java相关课程系列笔记之二Oracle学习笔记(建议用WPS打开) Java相关课程系列笔记之九Servlet...Java相关课程系列笔记之一Java学习笔记(建议用WPS打开)
这份“JAVA相关课件PPT”显然是一份关于学习Java的教育资源,适合初学者和有经验的开发者,旨在深化对Java语言的理解。 在PPT中,可能会涵盖以下关键知识点: 1. **Java基础**:包括基本语法、数据类型(如整型、...
综上所述,虽然具体的题目内容未知,但我们可以推测这是一个与Java源码分析或工具使用相关的技术问题。解决此类问题时,开发者需要具备扎实的Java语法基础,理解面向对象编程概念,熟悉常用的开发工具,并且有阅读和...
标题中的“一个轮询的Java案例”提示我们这个话题与编程中的轮询机制有关,而描述则提供了一个有趣的比喻,用以解释轮询的过程。在这个比喻中,20个人代表了程序中的多个参与者,3包降落伞相当于有限的资源,每数到...
7. **社区支持**:如果问题仍然存在,可以求助于Java开发者社区,提供详细的问题描述和相关日志,以便其他开发者提供帮助。 总的来说,Java的打印功能是强大的,但如同任何软件一样,可能会遇到一些挑战。通过深入...
Java问题定位技术是一份专注于Java应用性能分析和故障排除的专业文档。它详细介绍了如何通过Java线程堆栈分析来诊断和解决Java应用程序中的各种问题。文档从线程堆栈的输出和解读方法开始,逐步深入到具体的性能问题...
在给定的信息中,我们可以看到一系列与Java编程相关的文件。标题和描述中提到的"Java code"表明这些文件包含了Java编程语言的源代码。标签再次强调了这是与Java编程相关的内容,而压缩包子文件的文件名称列表列出了...
标题提到的问题——"java输入一个日期获得这是那一年的哪一天",其实是一个涉及到日期计算的问题。在Java中,我们可以使用`java.util.Date`、`java.time.LocalDate`或者`java.text.SimpleDateFormat`等类来实现这个...
Java是一种广泛使用的高级编程...总结来说,Java相关问题的详解与运用涵盖了语言基础、异常处理、集合框架、多线程、I/O流、反射、数据库访问等多个方面,全面理解和掌握这些知识点,将使你成为一位合格的Java开发者。
【东北大学JAVA实验一及实验二】涉及到的Java编程知识点广泛,涵盖了面向对象设计、异常处理、用户界面设计以及文件操作等多个方面。以下是对这些实验中可能出现的关键技术点的详细解释: 1. **UML类图**:统一建模...
压缩包中包含的"SR-2000+user's+manual_C (1).pdf"可能是一个设备手册或用户指南,这可能与JavaCV的某些应用有关,例如,如果SR-2000是一个摄像头或其他传感器设备,那么这个手册可能提供了如何使用该设备进行图像...