构建器&反射&JDBC

    xiaoxiao2026-09-25  13

    构建者模式(多可选参数)&静态工厂&单例设计模式

    一个营养产品类,该类含有两个必选参数和许多可选参数,代表了该营养产品的营养成分

    package xiaobai; public class NutritionFacts{ private final int servingSize; private final int servings; private final int calories; private final int fat; private final int sodium; private final int carbohydrate; public static class Builder{// Builder内部类,用来创建返回对象 // Required parameters,必选参数 private final int servingSize; private final int servings; // Optional parameters - initialized to default values,可选参数 private int calories = 0; private int fat = 0; private int carbohydrate = 0; private int sodium = 0; public Builder(int servingSize,int servings){ this.servingSize = servingSize; this.servings = servings; }// 每个设置参数的方法返回this,构建器 public Builder calories(int val){ calories = val; return this; } public Builder fat(int val){ fat = val; return this; } public Builder carbohydrate(int val){ carbohydrate = val; return this; } public Builder sodium(int val){ sodium = val; return this; } public NutritionFacts build(){// 返回类的对象 return new NutritionFacts(this); } }// 内部类结束 private NutritionFacts(Builder builder){// 单例设计模式-构造器私有化,静态工厂返回对象 servingSize = builder.servingSize; servings = builder.servings; calories = builder.calories; fat = builder.fat; sodium = builder.sodium; carbohydrate = builder.carbohydrate; } }

    创建对象时的代码:

    package xiaobai; import xiaobai.NutritionFacts; public class Test { public static void main(String[] args) { NutritionFacts cocaCola = new NutritionFacts.Builder(240,8) .carbohydrate(100).sodium(35).carbohydrate(27).build(); } }

    使用构建者模式在遇到有多个可选参数的类时,可以极大的简化代码,同时可以在创建对象时使代码更加的清晰易懂。而单例设计模式,私有化构造器,可以保证在一定情况下在所有的区域内只能存在一个该类的对象,本例中的对象不是唯一的。


    数组和List的相互转换

    一维数组与一维集合的转换 // 一维数组 转 一维集合 String[] strArr1 = {"one","two","three","four"}; List<String> list = Arrays.asList(strArr); // 一维集合 转 一维数组 String[] strArr2 = list.toArray(new String[]{}); 二维数组与二维集合的转换 // 二维数组 转 二维集合 String[][] strArr2 = { {"one","two","three","four"}, {"one","two","three","four"}, {"one","two","three","four"} }; // 对象创建使用多态,但泛型必须一致,左右都为List<String> List<List<String>> list = new ArrayList<List<String>>(); for(int i=0;i<strArr2.length;i++){ list.add(array2List(strArr2[i]));// 调用下面的方法 } // 完成一维数组转一维集合的功能 public static List<String> array2List(String[] strArr){ List<String> list = Arrays.asList(strArr); return list; }

    泛型

    给一个类或方法一个动态的参数类型,这样可以加强我们代码的复用性,一个类可以应用在所有类的情况,同时在使用时不会产生由于类型不明导致的编译错误。

    // 泛型类 public class GenericClass<E> { private E e; public E getE(){ return e; } public void setE(E e){ this.e = e; } public static void main(String[] args) { GenericClass<String> gc = new GenericClass<String>(); gc.setE("abc"); System.out.println(gc.getE()); } } // 泛型方法:修饰符和方法的返回值类型之间加泛型 public class GenericClass{ public <E> void swap(E e1,E e2){ System.out.println(e1 + ":" + e2); E temp = e1; e1 = e2; e2 = temp; System.out.println(e1 + ":" + e2); } public static void main(String[] args) { GenericClass gc = new GenericClass(); gc.swap("one", "two"); gc.swap(1, 2); } }

    枚举

    一个类中只有固定的几个该类的对象,如一个季节类中只有春、夏、秋、冬四个对象。此时就可以用枚举代替类,使代码简单清晰。如果不使用枚举,就需要使用单例模式,私有化构造器,然后将本类的对象作为本类的静态属性。

    // 交通信号灯类,只有红、绿、黄三个对象,就可以写为一个枚举。如果正常创建类 public enum LightEnum{ // 提供固定的几个本类对象作为该类的静态属性 public static final LightEnum RED = new LightEnum(); public static final LightEnum GREEN = new LightEnum(); public static final LightEnum YELLOW = new LightEnum(); private LightEnum(){// 私有化构造器 super(); } }

    写为一个枚举如下:

    public enum LightEnum { RED,GREEN,YELLOW;// 三个本类的对象 } // 测试类 public class TestEnum { public static void main(String[] args) { LightEnum le1 = LightEnum.RED; LightEnum le2 = LightEnum.GREEN; LightEnum le3 = LightEnum.YELLOW; System.out.println(le1); LightEnum[] leArr = LightEnum.values();// 返回枚举的所有对象 System.out.println(Arrays.toString(leArr)); } }

    反射

    在Java中,万物皆对象。那么我们将所有的类视为一个特殊的类的对象,每新建一个类就是给这个特殊类新建了一个对象。或我们起一个别名叫初代,而我们通常使用的类全部都是初代的对象,这个初代在Java官方给出的就是类Class。像String,Math,Object等都是初代的一个对象。而通过初代的方法来反向获取一个类和这个类中的属性、方法的过程就叫做反射。

    获取Class对象的方法 // 1、包名.类名 数据库驱动加载 框架中(从xml配置文件中根据类名称获取类对象,执行类的方法) Class c1 = Class.forName("cn.ucai.day26.Person"); // 2、多用于传参 Class c2 = Person.class; // 3、通过类的对象的方法返回一个Class对象 Person p = new Person(); Class c3 = p.getClass(); 通过反射获取类的所有方法 并可以执行方法 private static void showMethods(Class c) throws Exception{ // 获得所有的方法(修饰符、返回值类型、方法名、参数、抛出的异常) Method[] methodArr = c.getDeclaredMethods(); for(Method method : methodArr){ System.out.print(Modifier.toString(method.getModifiers())+" "); System.out.print(method.getReturnType().getSimpleName()+" ");// 返回值类型 System.out.print(method.getName()+" "); Class[] paArr = method.getParameterTypes();// 得到方法的参数类型 System.out.print(Arrays.toString(paArr)+" "); Class[] excArr = method.getExceptionTypes(); System.out.println(Arrays.toString(excArr)); } // 获得指定的方法 如何执行指定的方法 Method method = c.getDeclaredMethod("setName",new Class[]{String.class}); Person p = (Person) c.newInstance();// 调用Person的无参构造,创建Person对象 //method.setAccessible(true);使方法可见,打破了封装性 // 执行这个方法 method.invoke(p,"张三");// p.setName("张三"); Method methodGetName = c.getDeclaredMethod("getName"); String s = (String) methodGetName.invoke(p);// String s = p.getName(); System.out.println(s);// 张三 } 通过反射获取类的所有字段 并可以给字段赋值 private static void showFields(Class c) throws Exception{ Field[] fieldArr = c.getDeclaredFields(); for(Field field : fieldArr){ System.out.print(Modifier.toString(field.getModifiers())+" "); // java.lang.String ==> String System.out.print(field.getType().getSimpleName()+" "); System.out.println(field.getName()); } // 获得指定的属性 Field field = c.getDeclaredField("name"); Person p = (Person) c.newInstance();// Person p = new Person(); field.setAccessible(true); field.set(p, "张三");// p.setName("张三"); System.out.println(p); } 通过反射获取类的所有构造方法 并执行构造方法创建对象 private static void showConstructors(Class c) throws Exception{ // 取得所有的构造方法 Constructor[] conArr = c.getDeclaredConstructors(); for(Constructor con:conArr){ // 取得构造方法的修饰符 int modi = con.getModifiers(); String strModi =Modifier.toString(modi);// 对应数字转为了public 、private 等 System.out.print(strModi+" "); System.out.print(con.getName()+" "); // 得到参数的类型 Class[] claArr = con.getParameterTypes();// String.class int.class Class对象 System.out.print(Arrays.toString(claArr)+" "); // 得到异常的类型 Class[] excArr = con.getExceptionTypes();// Exception.class NullPointerException.class System.out.println(Arrays.toString(excArr)); } // 根据Class对象获得指定某个类的指定参数的构造方法并执行去创建对象 Constructor cons = c.getDeclaredConstructor(new Class[]{String.class,int.class}); cons.setAccessible(true);// 破坏类的封装性 Object o = cons.newInstance("张三",20);// new Person("张三",20); System.out.println(o.toString()); } 假如我们有两个程序员,一个程序员在写程序的时候,需要使用第二个程序员所写的类,但第二个 程序员并没完成他所写的类。那么第一个程序员的代码能否通过编译呢?这是不能通过编译的。利用Java反射的机制,就可以让第一个程序员在没有得到第二个 程序员所写的类的时候,来完成自身代码的编译。例如Tomcat中的代码就是采用了反射机制,我们在配置文件时采用了一下方式: <servlet> <servlet-name>Hello</servlet-name> <servlet-class>cn.ucai.servlet.HelloServlet</servlet-class> </servlet> <servlet-mapping> <servlet-name>Hello</servlet-name> <url-pattern>/hello</url-pattern> </servlet-mapping> // HelloServlet类中doGet方法被调用 在Tomcat的代码中: Class c = Class.forName("cn.ucai.servlet.HelloServlet"); HttpServlet hs = c.newInstance(); hs.doGet();

    MySQL数据库

    cmd窗口对于数据库的几个简单操作指令: show databases;–查看全部数据库 use 数据库名;–使用某指定数据库 select * from 表名;–查看某数据表中的全部数据

    下面是我目前使用的MySql数据库的下载连接: mysql-5.5.48 下面是安装教程: mysql安装教程 mysql数据库实现了很强大的数据库功能,但是操作只能在cmd窗口用命令行操作,有时非常不易操作,下面是一个mysql界面化的软件下载,下载完成后直接快速安装就可以: Navicat_Premium_11.0.10 最后是一个Navicat_Premium的破解工具: PatchNavicat


    JDBC(Java Database Connection)

    什么是JDBC:JDBC是我们代码与数据库相关联使用的语言

    使用代码完成数据的访问与操作 1.加载驱动 2.连接数据库 3.得到操作数据库的类 4.使用该类操作数据库 5.得到查询结果集 6.遍历结果集 7.断开连接

    在Eclipse相应工程src文件夹下创建一个配置文件jdbc.properties

    jdbcDriver=com.mysql.jdbc.Driver jdbcUrl=jdbc:mysql:/localhost:3306/xiaobai?user=root&password=root // xiaobai是要访问的数据库名,user、password是数据库的登录用户名和密码 获得配置文件中的值 public class PropertiesUtil { /** * 通过指定的key,取得properties文件中指定的value值 * @param key * @param proName 要访问的文件名 * @return */ public static String getValue(String key, String proName){ String value = null; Properties p = new Properties(); String path = PropertiesUtil.class.getResource("/").getPath(); try { // 指定p所表示的properties p.load(new FileInputStream(new File(path,proName))); value = p.getProperty(key); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return value; } } 创建一个工具类 /** * 数据库操作的工具类: * 1、完成数据库的连接 * 2、完成数据库的关闭 */ public class DBUtils { /** * 完成数据库的连接 * @return 数据库连接Connection对象 */ public static Connection getConnection(){ Connection conn = null; try { Class.forName(PropertiesUtil.getValue("jdbcDriver", "jdbc.properties")); conn = DriverManager .getConnection(PropertiesUtil.getValue("jdbcUrl", "jdbc.properties")); } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } return conn; } /** * 关闭全部内容 * @param conn * @param st * @param rs */ public static void closeAll(Connection conn,Statement st,ResultSet rs){ if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (st != null) { try { st.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } 访问数据库 public static List<Student> getAll() { List<Student> list = new ArrayList<Student>(); Connection conn = null; Statement st = null; ResultSet rs = null; try { // 获取连接 conn = DBUtils.getConnection(); // 得到操作数据库的类的对象 st = conn.createStatement(); // 通过executeQuery,执行查询的sql语句,数据库中要存在该表 rs = st.executeQuery("select * from t_student"); // 遍历结果集 // rs.next();// 相当于Iterator中的hasNext()和next() while (rs.next()) { // 根据字段,取数据 int id = rs.getInt("sid"); String name = rs.getString("name"); int age = rs.getInt("age"); // 实体类,对应t_student数据表中的各列,一个对象代表数据库中一行数据 Student student = new Student(id, name, age); list.add(student); } } catch (SQLException e) { e.printStackTrace(); } finally { // 关闭内容 DBUtils.closeAll(conn, st, rs); } return list; }
    转载请注明原文地址: https://ju.6miu.com/read-1312327.html
    最新回复(0)