反射機制:
在運行狀態中,對於任意一個類,都能夠獲取到這個類的所有屬性和方法,對於任意一個對象,都能夠調用它的任意一個方法和屬性(包括私有的方法和屬性),這種動態獲取的信息以及動態調用對象的方法的功能就稱爲java語言的反射機制。通俗點講,通過反射,該類對我們來說是完全透明的,想要獲取任何東西都可以。
編程語言的分類:
1.非動態語言
相反靜態類型語言是在執行前編譯時檢查類型。
2.動態語言
程序運行時,動態改變變量的類型,爲動量增加,刪除 屬性和方法
在執行期間檢查數據的類型的語言。
非動態語言:c,c++,java
動態語言:js,python
java不是動態語言,可以通過反射技術來實現動態語言的部分特徵
java反射機制:
java反射機制是在運行狀態中,動態分析類的能力
Class類
具體來說
1.運行時,可以根據類名來動態加載類
Class.forName();
2.可以獲得某個類的信息
3.可以動態調用類內的所有方法(包括私有)
Class類:
Class類代表加載到java虛擬機裏的類實例,每個類只加載一次,每個類只有唯一的實現,通過這個類實例,我們可以獲得所有的元數據
獲得Class實例的方法:
1.Class c=Book.class;
2.Class c=Class.forName(“類或完整路徑名”);
3.Class c = obj.getClass();
獲得int類:
int.Class();
integer.Type();
Class中常用的方法:
獲得成員變量並使用:Field類:
對屬性元數據的封裝;
獲得方法並使用: Method
反射機制的應用:
封裝一個通用的dao
package dao;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import util.JdbcUtil;
import vo.Pk;
import vo.TableName;
public class CommonDaoImpl implements CommonDao {
@Override
public <T> List<T> query(Class<T> clazz, String sql, Object... args) throws Exception {
// TODO Auto-generated method stub
List <T> list = new ArrayList<T>();
try(Connection conn = JdbcUtil.getConnections();
PreparedStatement ps = conn.prepareStatement(sql)){
for(int i=0;i<args.length;i++) {
ps.setObject(i+1, args[i]);
}
ResultSet rs = ps.executeQuery();
Field[] fs = clazz.getDeclaredFields();
while(rs.next()) {
T obj = clazz.newInstance();
for(Field f:fs) {
f.setAccessible(true);
if(f.getType()==Integer.class) {
f.set(obj, rs.getInt(f.getName()));
}else if(f.getType()==String.class) {
f.set(obj, rs.getString(f.getName()));
}else
f.set(obj, rs.getObject(f.getName()));
}
list.add(obj);
}
} catch (SQLException e) {
e.printStackTrace();
}
return list;
}
@Override
public int executeSql(String sql, Object obj) {
// TODO Auto-generated method stub
int count=0;
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
Field[] fs = c.getDeclaredFields();
try(Connection conn = JdbcUtil.getConnections();
PreparedStatement ps = conn.prepareStatement(sql.toString())
){
int num=1;
for(Field f:fs) {
if(!f.isAnnotationPresent(Pk.class)) {
f.setAccessible(true);
Object value = f.get(obj);
ps.setObject(num, value);
num++;}
}
count=ps.executeUpdate();
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return count;
}
public String tablename(Object obj) {
// TODO Auto-generated method stub
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename = c.getSimpleName();
@SuppressWarnings("unchecked")
TableName t =(TableName)c.getAnnotation(TableName.class);
if(t!=null) {
tablename=t.tablename();
}
return tablename;
}
public void insert(Object obj) throws Exception {
// TODO Auto-generated method stub
{
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename=tablename(obj);
StringBuffer sql = new StringBuffer("insert into "+tablename+"(");
StringBuffer values = new StringBuffer(" values(");
Field[] fs = c.getDeclaredFields();
for(int i=0;i<fs.length;i++)
{
if(i==fs.length-1) {
sql.append(fs[i].getName()+")");
if(fs[i].isAnnotationPresent(Pk.class))
values.append("null)");
else
values.append("?)");
}
else {
sql.append(fs[i].getName()+",");
if(fs[i].isAnnotationPresent(Pk.class))
values.append("null,");
else
values.append("?,");
}
}
sql.append(values);
System.out.println(sql.toString());
if(executeSql(sql.toString(),obj)==0) {
System.out.println("插入失敗");
}else {
System.out.println("插入成功");
}
}
}
@Override
public boolean delete(Object obj,int id) throws Exception {
// TODO Auto-generated method stub
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename=tablename(obj);
StringBuffer sql = new StringBuffer("delete from "+tablename+" where ");
Field[] fs = c.getDeclaredFields();
for(Field f:fs) {
if(f.isAnnotationPresent(Pk.class)) {
sql.append(f.getName()+" = "+id);
}
}
try(Connection conn = JdbcUtil.getConnections();
PreparedStatement ps = conn.prepareStatement(sql.toString())){
if(ps.executeUpdate()==0) {
System.out.println("沒有主鍵爲"+id+"的記錄");
}
else {
System.out.println("成功刪除主鍵爲"+id+"的記錄");
}
}catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return true;
}
@Override
public boolean update(Object obj,int id) throws Exception{
// TODO Auto-generated method stub
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename=tablename(obj);
StringBuffer sql = new StringBuffer("update "+tablename+" set ");
Field[] fs = c.getDeclaredFields();
String id1 = null;
for(int i=0;i<fs.length;i++)
{
if(fs[i].isAnnotationPresent(Pk.class)) {
id1=fs[i].getName();
}
if(!fs[i].isAnnotationPresent(Pk.class)&&i!=fs.length-1) {
sql.append(fs[i].getName()+" =?,");
}
else if(!fs[i].isAnnotationPresent(Pk.class)){
sql.append(fs[i].getName()+" =? where ");
}
}
sql.append(id1+" = "+id);
System.out.println(sql.toString());
if(executeSql(sql.toString(),obj)==0)
{
System.out.println("更新失敗!");
return false;
}
else {
System.out.println("更新成功!");
return true;
}
}
@SuppressWarnings("unchecked")
@Override
public List<?> getAll(Object obj) throws Exception {
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename=tablename(obj);
StringBuffer sql = new StringBuffer("select * from "+tablename);
return query(c, sql.toString());
}
@SuppressWarnings("unchecked")
@Override
public List<?> selectByid(Object obj,int id) throws Exception {
@SuppressWarnings("rawtypes")
Class c = obj.getClass();
String tablename=tablename(obj);
StringBuffer sql = new StringBuffer("select * from "+tablename+" where ");
for(Field fs:c.getDeclaredFields()) {
if(fs.isAnnotationPresent(Pk.class))
sql.append(fs.getName());
}
sql.append("=?");
return query(c, sql.toString(),id);
}
}