階段項目的總結(正則, MD5, 數據庫查詢的反射問題)等等

1. protected 屬性的子類對象的調用問題

  1. 無論是否在同一個包裏面, 子類都可以調用父類的protected的任意屬性和方法.
  2. 在不同的包和不同的類裏面, 子類的對象不可以訪問父類的protected屬性和方法.
  3. 一般情況下, 我們可以認爲, 對於protected的修飾的屬性和方法, 子類繼承之後, 對於別的類來說相當於私有, 也就是在別的類中, 子類的對象不可以訪問.

2. Java Constructor 的同類型參數個數的函數重載問題

  1. 在我做某一個項目的時候, 我使用了幾個不同的構造方法, 但是屬性的類型都是String類型的.
  2. 在我向數據庫中插入的時候, 會發現數據長度問題錯誤.
  3. 仔細檢查後發現是構造方法的重載問題, 使用了同樣個數的參數, 但是賦值的時候, 程序只認構造方法的類型, 和個數, 類型和個數匹配後, 程序不會考慮別的, 只是一一賦值, 但是賦值的時候不一定是按照開發者的想法來進行賦值.
  4. 在使用構造方法時, 一定要檢查參數的個數和類型是否匹配.

3. 托盤圖標的創建以及移除問題

  1. 我們可以使用System Tray這個類來創建以及生成Java GUI Swing或者AWT的托盤圖標.

  2. 測試代碼

    import java.awt.Image;
    import java.awt.MenuItem;
    import java.awt.PopupMenu;
    import java.awt.SystemTray;
    import java.awt.Toolkit;
    import java.awt.TrayIcon;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    import java.awt.event.WindowAdapter;
    import java.awt.event.WindowEvent;
    
    import javax.swing.JFrame;
    
    /**
     * 測試托盤區的圖標問題
     *
     * @author Master_Joe [email protected]
     *
     */
    public class TestSystemTray extends JFrame {
    	/**
    	 * 
    	 */
    	private static final long serialVersionUID = 1L;
    	private TrayIcon trayIcon;
    	private SystemTray systemTray;
    	private PopupMenu rightKeyJPopupMenu;
    	private MenuItem menuItem1;
    	
    	public TestSystemTray() {
    		super("System tray test");
    		systemTray = SystemTray.getSystemTray();
    		setSize(150, 150);
    		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		this.setVisible(true);
    		try {
    			String filePath = "resources/RegisterImages/Profiles/0_online.png";
    			Image image = Toolkit.getDefaultToolkit().getImage(filePath);
    			trayIcon = new TrayIcon(image);
    			systemTray.add(trayIcon);
    			this.dispose();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		
    		this.addWindowListener(new WindowAdapter() {
    			@Override
    			public void windowIconified(WindowEvent e) {
    				dispose();
    			}
    		});
    		
    		trayIcon.addMouseListener(new MouseAdapter() {
    			@Override
    			public void mouseClicked(MouseEvent e) {
    				if (e.getClickCount() == 2) {
    					setExtendedState(NORMAL);
    				}
    				setVisible(true);
    			}
    		});
    		
    		
    		rightKeyJPopupMenu = new PopupMenu();
    		menuItem1 = new MenuItem("Exit");
    		rightKeyJPopupMenu.add(menuItem1);
    		
    		trayIcon.setPopupMenu(rightKeyJPopupMenu);
    		
    //		trayIcon.addMouseListener(new MouseAdapter() {
    //			
    //			@Override
    //			public void mousePressed(MouseEvent e) {
    //				rightKeyJPopupMenu.setVisible(true);
    //			}
    //		});
    		
    	}
    	
    	public static void main(String[] args) {
    		new TestSystemTray();
    	}
    	
    }
    
    

3.1 AWT的中文亂碼

  • 在使用托盤的彈出菜單時, 我們只能使用PopupMenu這個組件來進行設置, 但是使用這個方法會產生亂碼問題
  • 我的電腦時英文的System, 我的文件系統編碼格式時UTF-8, 同時JVM也是UTF-8啓動的, 但是使用AWT的MenuItem這個組件進行添加菜單的功能描述的時候, 在右下角的托盤圖標的菜單會顯示方格的亂碼
  • 我使用String類裏面的getBytes(String charsetName) 這個方法獲取了UTF-8的字符串, 沒有什麼用, 然後又獲取了GBK的字符串, 結果換了一種新的亂碼, 反正也是亂碼, 然後我從網上搜索到的解決方案是在JVM的參數上加了一行**-DFile.encoding=GBK然後就好了, 但是隨之而來的就是我的控制檯的中文顯示全部變成了亂碼, 無奈, 只好使用了English**這種神奇的不會發生亂碼的語言.

4. 數據庫查詢工具的反射問題

  1. 我在數據庫查詢的時候使用了Apache的DbUtils工具, 使用QueryRunner類來進行查詢

  2. 使用QueryRunner的查詢方法時, 如果我們要求要返回一個Java Bean的對象, 除了必須要提供一個空參構造器之外, 還要進行如下的考量

    • 要清楚的知道自己的Java Bean所對應的表格的字段名和自己Java Bean的屬性名是否一致, 如果不一致要使用別名來讓我們的QueryRunner類中使用的ResultSetHandler的返回的Java Bean 的對象認識

    • 假使我們的數據庫表的字段名是user_name, user_password, 但是我們的Java Bean 中的是name 和 password 屬性, 那麼我們在使用QueryRunner 類進行查詢時候就要用別名的方式來進行查詢

    • select user_name as name, user_password as password from user_table where id = ? # 如果表中字段和我們的Java Bean不同的話, 我們可以使用這個方式. 
      

5. 保存文件窗口的自動補全名稱問題

  1. 在我們的Java中的JFileChooser在進行保存文件時, 需要自己輸入文件名, 但是我們又需要這樣一個功能, 因此, 我們可以使用下面這個通用的方法來獲取我們的文件選擇框的Text Field, 然後使用setText設置一下文件的名字.

    /**
     * 獲取我們的JTextField, 從我們的容器 {@code c}中
     * @param c 容器
     * @return 返回我們的TextField 框
     */
    public JTextField getTextField(Container c) {
    	JTextField textField = null;
    	for (int i = 0; i < c.getComponentCount(); i++) {
    		Component cnt = c.getComponent(i);
    		if (cnt instanceof JTextField) {
    			return (JTextField) cnt;
    		}
    		if (cnt instanceof Container) {
    			textField = getTextField((Container) cnt);
    			if (textField != null) {
    				return textField;
    			}
    		}
    	}
    	return textField;
    }
    

6. JTable的判空

  • 只需要判斷.getRowsCount()==0的結果就好了

7. 屬性(Field)初始化問題

  • 我們的屬性中的數組初始化, 是在構造方法之前進行初始化, 如果我們的屬性(Field)數組裏面存在着構造方法的參數相關的元素, 很有可能會出現空指針的現象.

8. String 的MD5摘要算法

  • MD5摘要算法一般用在加密方面. MD5的摘要是一個32位的十六進制數組成的字符串. 可以作爲密碼的一種存儲方式, 當我們在進行密碼驗證的時候, 可以通過比對這個MD5的摘要信息進行判定是否密碼正確.

  • 代碼如下

    import java.security.MessageDigest;
    
    /**
     * MD5的工具類, 將字符串轉換爲MD5摘要
     *
     * @author Master_Joe [email protected]
     *
     */
    public class MD5Utils {
        
        /** 
         * 因爲數據庫中我們的存儲數據是沒有大寫小寫的, 因此可以使用大寫, 也可以使用小寫
         */
    	private final static String[] hexArray = { "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d",
    			"e", "f" };
    
    	/***
    	 * 對指定的字符串進行MD5加密
    	 */
    	public static String encrypByMD5(String originString) {
    		try {
    			// 創建具有MD5算法的信息摘要
    			MessageDigest md = MessageDigest.getInstance("MD5");
    			// 使用指定的字節數組對摘要進行最後更新,然後完成摘要計算
    			byte[] bytes = md.digest(originString.getBytes());
    			// 將得到的字節數組變成字符串返回
    			String s = byteArrayToHex(bytes);
    			return s.toUpperCase();
    		} catch (Exception e) {
    			e.printStackTrace();
    		}
    		return null;
    	}
    
    	/**
    	 * 將字節數組轉換成十六進制,並以字符串的形式返回 128位是指二進制位。二進制太長,所以一般都改寫成16進制,
    	 * 每一位16進制數可以代替4位二進制數,所以128位二進制數寫成16進制就變成了128/4=32位。
    	 */
    	private static String byteArrayToHex(byte[] b) {
    		StringBuffer sb = new StringBuffer();
    		for (int i = 0; i < b.length; i++) {
    			sb.append(byteToHex(b[i]));
    		}
    		return sb.toString();
    	}
    
    	/**
    	 * 將一個字節轉換成十六進制,並以字符串的形式返回
    	 */
    	public static String byteToHex(byte b) {
    		int n = b;
    		if (n < 0)
    			n = n + 256;
    		int d1 = n / 16;
    		int d2 = n % 16;
    		return hexArray[d1] + hexArray[d2];
    	}
    }
    
    

9. 郵箱的正則表達式

  • 在輸入註冊信息時, 我們經常會有郵箱的輸入, 但是如果不加限制的話, 用戶可能會隨便輸入錯誤的郵箱, 因此, 郵箱的驗證尤爲重要, 在Java中我們可以使用一個叫做正則表達式的東西來進行郵箱格式的判斷問題

  • 代碼如下

    // 驗證郵箱格式是否正確
    // mailRegex是整體郵箱正則表達式,mailName是@前面的名稱部分,mailDomain是後面的域名部分
    String mailName = "^[0-9a-z]+\\w*"; // ^表明一行以什麼開頭;^[0-9a-z]表明要以數字或小寫字母開頭;\\w*表明匹配任意個大寫小寫字母或數字或下劃線
    String mailDomain = "([0-9a-z]+\\.)+[0-9a-z]+$"; // ***.***.***格式的域名,其中*爲小寫字母或數字;第一個括號代表有至少一個***.匹配單元,而[0-9a-z]$表明以小寫字母或數字結尾
    String mailRegex = mailName + "@" + mailDomain; // 郵箱正則表達式 ^[0-9a-z]+\w*@([0-9a-z]+\.)+[0-9a-z]+$
    Pattern pattern = Pattern.compile(mailRegex);
    Matcher matcher = pattern.matcher(emailField.getText());
    if (matcher.matches() || "".equals(emailField.getText())) {
        String email = emailField.getText();
    }
    

10. JPopupMenu的元素問題

  • 當我們在使用這個JPopupMenu組件的時候, 如果我們要使用數組來進行內容的填充的話, 那麼我們在使用, setSelectedItem(Object object) 這個方法的時候, 我們不能將數組之外的元素設置在我們的選擇框中.

11. Git&GitHub&Gitee

  • 如果在使用Gitee或者GitHub託管的時候, 如果是先在網站上新建一個倉庫, 然後再進行託管的話, 有可能推送失敗.

  • 我們需要在本地的Git命令窗口裏面使用

    git pull --rebase
    

    這個命令會使我們遠程庫, 和本地庫之間進行一個融合, 只是一個線性融合, 主要是因爲我們Gitee.com網站創建的時候會出現一個ReadMe.en.md的文件, 這個文件需要與我們本地庫的文件進行融合.

12. 總結

  • 通過這個Swing簡單項目, 我的解決問題能力提升了, 代碼耐心也有了提高, 對於Git&GitHub&Gitee的使用更加的熟練了.

  • 如果有錯誤, 歡迎評論區留言, 或者郵件聯繫我

    qiaoguangtong@aliyun.com
    
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章