⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 java常见问题.txt

📁 java面试题-外企软件工程师面试题大全,欢迎想到外企工作的人作为参考
💻 TXT
📖 第 1 页 / 共 2 页
字号:

myFORM = processActionFORM(myFORM); 

其中myFORM是一个对象, 它在传递到processActionFORM中去做处理的时候, 先用另外一个otherFORM去接了一下, 这个时候otherFORM也就指向myFORM的句柄, 而在外面再用myFORM去接返回值, myFORM这个时候其实还是指向原来的句柄。 虽然结果没错, 但这个时候有个问题就是同时有两个别名指向同一个句柄。 执行其中任何一个别名的方法, 另一个别名的对象也随着改变了。 所以上面的这个例子要尽量改写为: 

private void processActionFORM(SomeActionFORM myFORM) { 



myFORM….. 

…; 



return otherFORM; 

} 

调用如下: 

processActionFORM(myFORM); 

特别在画面之间传递参数的时候, 除非你能保证你的数据不被别人篡改, 否则你就得小心, 或者你需要重新clone一个对象传过去, 然后取返回值。 

注: 如果在EJB的client与server之间传递参数, 则不存在句柄的传递, 数据在server端修改之后client端并不改变。 因为它们是通过网络进行Object字节流传输的, 不存在句柄地址相同的条件。 你尽可放心的使用, 最后如果client端需要再使用这个新的Object, 则需要再回传过去。 (EJB2.0 支持local interface, 这种情况下有可能就跟前面所说的句柄传递一样了, 没试过)。 



4.2 String的特殊性 
String在Java中被设计成安全的String, 对于String的任一个操作都是先重新生成一个String的拷贝, 然后对这个拷贝进行操作。 所以String在参数传递的时候可以看作是值传递。 即如果你需要修改一个String并返回修改后的String, 你得要再去接一下返回值。 如: 

String str = “This is a sample”; 

str = editStr(str); 

System.out.println(str); // “Here is a sample” 



private String editStr(String str) { 

String newStr = str. substring(4); 

newStr = “Here” + newStr; 



return newStr; 

} 

如果想用句柄传递, 可以使用String的内部操作使用的一个类StringBuffer, 对它的操作都是同一个对象上进行的, 所以效率也自然高一些。 上面的例子用StringBuffer改写如下: 

StringBuffer str = new StringBuffer(“This is a sample”); 

editStr(str); 

System.out.println(str); // “Here is a sample” 



private void editStr(StringBuffer str) { 

str.replace(0, 4, “Here”); 

} 



5. 例外处理 
有些新手总是习惯于使用返回值来进行错误处理, 如果使用异常处理这种方法将会使程序结构更合理, 效率更高。 比如在Client端需要通过EJB来进行DB操作, Client端需要知道DB处理有没有出错就可以通过层层的向上抛Exception的方法, 一直到Client端需要处理的地方截住, 然后进行例外处理。 如: 

后台DB处理: 

public static java.sql.Timestamp getDBSysdate() throws CSCWebException { 

Connection conn = null; 

Timestamp sysTime = null; 



try { 

conn = PJEJBSvrUtil.getWLPoolConnection(); 

sysTime = CommonDAO.getDBSysdate(conn); 

} catch (SQLException ce) { 

throw new CSCWebException(ce.getMessage()); 

} finally { 

try { 

if (conn != null) { 

conn.close(); 

} 

} catch (Exception e) { 

throw new CSCWebException(e.getMessage()); 

} 

} 



return sysTime; 

} 

在前台: 

try { 

commonIntf.getDBSysdate(); 

} catch (CSCWebException cex) { 

cat.debug(“”, cex); 

return getExceptionForward(cex); 

} 

要防止违例被漏处理, 除非是你肯定不需要处理的, 提倡在遇到Exception的时候就要往上抛, 由最终调用处来进行处理, 当然也不能一概而论, 视情况而定。 比如我想例外在方法体内就要解决掉, 给出一个CSC中出现的bug。 

public boolean checkTelFORMat(String telNo) { 

boolean error = false; 



if ( telNo == null || telNo.equals("") ) { 

error = true; 

} else { 

if ( ejb.util.StringUtil.chkPhone(telNo) ) { 

error = false; 

} else { 

error = true; 

} 

} 



if (telNo.startsWith("184") || telNo.startsWith("186")) { 

if (telNo.length() == 3) { 

error = true; 

} 

} 



if ( error ) { 

ObjMngr.showError("MCSTC001E"); 

cmbTelNo.requestFocus(); 

return false; 

} else { 

return true; 

} 

} 

用了一个Flag来记住每次Check的结果, 然后在最后再出Error Dialog, 这是比较典型的C的写法, 改写如下: 

public boolean checkTelFORMat(String telNo) { 

try { 

if (telNo == null || telNo.equals("")) { 

throw new Exception(); 

} else { 

if (!ejb.util.StringUtil.chkPhone(telNo)) { 

throw new Exception(); 

} 

} 

if (telNo.startsWith("184") || telNo.startsWith("186")) { 

if (telNo.length() == 3) { 

throw new Exception(); 

} 

} 

} catch (Exception e) { 

ObjMngr.showError("MCSTC001E"); 

cmbTelNo.requestFocus(); 

return false; 

} 



return true; 

} 

使用了抛Exception的方法, 在方法的最后截住, 这样一遇到Error就能马上处理掉, 从效率上讲也是最高的。 

6.数据库操作的问题 
根据现有的开发经验, 一般我们在SessionBean(或不用EJB的时候的Module Bean)中取到Connection然后调用专门操作数据库(DAO)中的方法, 也就是在Bean中进行Connection的打开与关闭操作, 而在DAO中进行Statement和ResultSet操作, 一般在最后都需要进行关闭它们。 接上节的例子, 在CommonDAO里面有这样的一个方法: 

public static java.sql.Timestamp getDBSysdate(Connection conn) 

throws CSCWebException { 

Statement stmt = null; 

ResultSet rs = null; 

Timestamp sysTime = null; 



try { 

stmt = conn.createStatement(); 

rs = stmt.executeQuery("SELECT SYSDATE FROM DUAL"); 

if (rs.next()) { 

sysTime = rs.getTimestamp("SYSDATE"); 

} 

} catch (SQLException ce) { 

throw new CSCWebException(ce.getMessage()); 

} catch (Exception e) { 

throw new CSCWebException(e.getMessage()); 

} finally { 

try { 

if (rs != null) { 

rs.close(); 

} 

if (stmt != null) { 

stmt.close(); 

} 

} catch (Exception e) { 

throw new CSCWebException(e.getMessage()); 

} 

} 



return sysTime; 

} 

在finally里面的语句总是会被执行到的, 所以即使上面抛出了SQLException也会去执行stmt与rs的close操作的。 



7. index越界 
index越界包括很多: 

Ø String的index 

String的index从0开始, 最大为它的字符长度。常用的为substring这个方法: 

String str = “This is a sample”; 

str.substring(5, 7); 返回 is; 



str.substring(15, 16) 或 str.substring(15); 都返回最后一个字符 e; 



str.substring(16, 17); 这个会抛java.lang.StringIndexOutOfBoundsException错误; 



Ø 数组下标 

数组下标也由0开始, 最大为长度-1, 例: 

int[] columnLen = new int[]{20, 30, 40, 30, 25, 50, 65, 100}; 

columnLen[0]为20; 

columnLen[7]为100; 

columnLen[8]会抛java.lang.ArrayIndexOutOfBoundsException错误。 



Ø Vector, ArrayList等Collection的size 

Vector与ArrayList同属于List, 它们都是有序的集合体, 下标也都是从0开始, 最大也是长度-1, 跟数组不同的是, 它们的元素必须都是Object, 但可以为不同类型的对象, 不过在取出之后得要进行类型转换。 而数组得要所有元素的类型相同。 ArrayList在构造之后, 并不存在元素的情况下, 如果调用set(index, Object)就会出错。得要先进行add(Object)才行。 例: 

ArrayList list = new ArrayList(10); // 这个地方的10只是list的初始容量, 并不代表它具有了10个元素, 这个跟数组不同, 数组在这种情况下具有了10个初始值, 初始值跟具体的元素类型有关, 一般的对象为null; 

list.set(0, “First”); // 会抛java.lang.IndexOutOfBoundsException 

list.add(“First”); 

list.set(0, “new First”); // 正确, 因为位置0已经存在元素 



8.其它 
具体到每个项目, 不同的API使用都还有可能遇到一些共通的问题。 需要在项目开始的时候进行必要的培训, 往往给出一个好的sample会事半功倍。 

还用一些问题在此不再详细描述: 

ü 大小写问题(String.equals()与String.equalsIgnoreCase(), 变量名等) 

ü 括号匹配问题 

ü 。。。 



9.有待讨论的问题 
9.1 方法返回地点 
private int getStatus( String sFlag ){ 

if (CodeBook.STATUS_OK_NAME.equals( sFlag )) { 
return CodeBook.STATUS_OK_value; 
} else if (CodeBook.STATUS_OK1_NAME.equals( sFlag )) { 
return CodeBook.STATUS_OK1_value; 
} else if (CodeBook.STATUS_NG_NAME.equals( sFlag )) { 
return CodeBook.STATUS_NG_value; 
} 


return CodeBook.STATUS_NG_value; 
} 


private int getStatus(String sFlag) { 

int iStatus = CodeBook.STATUS_NG_value; 



if (CodeBook.STATUS_OK_NAME.equals(sFlag)) { 

iStatus = CodeBook.STATUS_OK_value; 

} else if (CodeBook.STATUS_OK1_NAME.equals(sFlag)) { 

iStatus = CodeBook.STATUS_OK1_value; 

} else if (CodeBook.STATUS_NG_NAME.equals(sFlag)) { 

iStatus = CodeBook.STATUS_NG_value; 

} 



return iStatus; 

} 



9.2 变量声明点 
例: 

for (int i = 0; i < 10; i++) { 

String sTmp = String.valueOf(i); 

... 

} 


String sTmp = null; 

for (int i = 0; i < 10; i++) { 

sTmp = String.valueOf(i); 

... 

} 

  
 

--------------------------------------------------------------------------------
 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -