构建者模式(多可选参数)&静态工厂&单例设计模式
一个营养产品类,该类含有两个必选参数和许多可选参数,代表了该营养产品的营养成分
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;
}
661

被折叠的 条评论
为什么被折叠?



