反射的常用api

目录

主要内容

反射的作用

一、什么是反射?

二、类加载的过程

三、类加载的时机 

四、类对象

五、类加载器

六、类对象的三种获取方式 

七、类对象的常用API 

 八、Field的常用API 

 九、Method的常用API 

 十、Constructor的常用API 

 十一、JDBC利用反射来封装工具类


主要内容

1.反射的基本知识

2.Class、Field、Method、Constructord的常用方法

3.JDBC利用反射的封装


反射的作用

可以实现动态创建对象和编译,提现出很大的灵活性(运行期间)


公共的代码

​
package com.sofwin.work;

public class Account {
 private String name ;
 private Integer money;
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public Integer getMoney() {
	return money;
}
public void setMoney(Integer money) {
	this.money = money;
}
@Override
public String toString() {
	return "Account [name=" + name + ", money=" + money + "]";
}
 

}

​
package com.sofwin.work;

import java.io.Serializable;

public class Student implements Serializable {

}

 

 

一、什么是反射?

在运行期间动态的获取类、方法的相关信息
Java的反射(reflection)机制是指在程序的运行状态中,可以构造任意一个类的对象,可以了解任意一个对象所属的类,可以了解任意一个类的成员变量和方法、类,可以调用任意一个对象的属性和方法。这种动态获取程序信息以及动态调用对象的功能称为Java语言的反射机制。反射被视为动态语言的关键。基本上以后的框架底层都是用到了反射机制

二、类加载的过程

1.加载
  将编译生产的字节码文件加载到jvm中(运行时区的方法区)
2.连接
   验证:验证字节码是否合法
   准备:为静态成员变量分配空间
   解析:将java中的符号引用改为直接引用 
3.初始化

三、类加载的时机 

1.new 对象

2.调用静态方法

3.调用静态成员变量

4.子类调用父类的构造方法

四、类对象

类:是对象的模板

对象:是类的实例、

类对象:类对象就是描述这种类,有什么方法,有什么属性等。

特点:有且仅有一个类对象。该类的所以实例共用一个类对象

验证该类的所以实例共用一个类对象

package com.sofwin.pojo;

import java.io.Serializable;

public class User implements Serializable {
	
  private  Integer id;
  private String name ;
  public Integer getId() {
	return id;
  }
  public void setId(Integer id) {
	this.id = id;
  }
  public String getName() {
 	return name;
  }
  public void setName(String name) {
	this.name = name;
  }
  
   
}
class Demo {
public static void main(String[] args)  {
        User user=new User();
        User user2=new User();
        //类对象
        Class clazz1=User.class;
        Class clazz2=user.getClass();
        Class clazz3=user2.getClass();
        System.out.println(clazz1==clazz2);
        System.out.println(clazz1==clazz3);
        System.out.println(clazz2==clazz3);
}
}

最后结果都是true     ---这说明了 有且仅有一个类对象。该类的所以实例共用一个类对象

五、类加载器

根类加载器  bootstrap classloader  
  用于加载jdk中lib中的.jar的文件中的类

扩展类加载器  extention classloader
  用于加载jdk中lib中ext下的类
  
系统类加载器 system classloader
  用于加载我们自定义的类和第三方框架提供的类  (druid中的java类的加载)
  
自定义类加载器

六、类对象的三种获取方式 

1.static Class forName(String className)  --通过全限类名来获取类对象  

2.通过类名点class属性来获取类对象 

3.通过对象实例的getClass()方法来获取类对象

class Demo {
public static void main(String[] args)  {
        User user=new User();
        User user2=new User();
        //类对象的三种创建方式
        //1.类名点class属性获取类对象
        Class clazz1=User.class;
        //2.对象名的getClass()方法
        Class clazz2=user.getClass();
        Class clazz3=user2.getClass();
       //3.forName来获取
        Class  clazz111=Class.forName("com.sofwin.pojo.User");
}
}

七、类对象的常用API 

方法名返回结果描述
 forName(String className)   --静态的Class通过全限定名来获取类对象
   getClassLoader()ClassLoader获取类加载器
   getName()String返回该类对象的全限定名称
  getModifiers()int获取该类对象的修饰符
. getSuperclass()Class 返回该类对象的父类  因为java是单继承因此是一个
 getInterfaces()Class[] 获取类的所有接口  --注意这里的接口这是指是这个类  不包含其父类的接口
newInstance  Object利用反射创建对象   ---注意这里的类一定要有无参构造方法才能创建(依赖无参构造创建)

常用反射对应修饰符的常量表

package com.sofwin.work;
/**
 * Class类对象的常用方法
 * @author wentao
 *
 */
public class ClassDemo {
    
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
	//Class的相关方法
		//1.static Class forName(String className)  --通过全限类名来获取类对象  
		  //可能出现的异常 --->  ClassNotFoundException   无法找到指定的类异常
		Class User = Class.forName("com.sofwin.work.User");
		System.out.println(User);   //class com.sofwin.work.User
		
		//2.ClassLoader getClassLoader()   --放回类的加载器
		ClassLoader classLoader = User.getClassLoader();  //sun.misc.Launcher$AppClassLoader@1d16e93
		System.out.println(classLoader);
		
		//3.String getName() 返回该类对象的全限定名称
		String name = User.getName();
		System.out.println(name);  //com.sofwin.work.User  全限定类名  包.类
        
		//4.int getModifiers()  获取该类对象的修饰符  ---public对应的是1  
             /*
              * public static final int ABSTRACT 1024 
 				public static final int FINAL 16 
 				public static final int INTERFACE 512 
 				public static final int NATIVE 256 
 				public static final int PRIVATE 2 
 				public static final int PROTECTED 4 
 				public static final int PUBLIC 1 
 				public static final int STATIC 8 
 				public static final int STRICT 2048 
 				public static final int SYNCHRONIZED 32 
 				public static final int TRANSIENT 128 
 				public static final int VOLATILE 64 
              * 
              * */
         int modifiers = User.getModifiers();
         System.out.println(modifiers);   //1
         
         //5.Class getSuperclass()  返回该类对象的父类  因为java是单继承因此是一个
         Class superclass = User.getSuperclass();
         System.out.println(superclass.getName()); //java.lang.Object
         
         //6.Class[] getInterfaces()  获取类的所有接口  --注意这里的接口这是指是这个类  不包含其父类的接口
         Class[] interfaces = User.getInterfaces();
         for( Class clazz:interfaces) {
        	 System.out.println(clazz.getName());
         }
         
         //7.T newInstance  利用反射创建对象   ---注意这里的类一定要有无参构造方法才能创建(依赖无参构造创建)
         Object newInstance = User.newInstance();
         System.out.println(newInstance);   //User [id=null, name=null]
        
		
      
	}

}

 八、Field的常用API 

方法名返回结果描述
 getFields()  Field[]获取所以public修饰的成员变量
 getDeclaredFields()  Field[] 获取所有的成员变量
 getField(String name)   Field 通过名称来获取public修饰成员变量
 getDeclaredField(String name)  Field 通过名称来获取成员变量对象
.get类型(Object obj)      Objectobj对象的当前属性的值
set类型(Object obj)Class[]   obj对象的当前属性的值
package com.sofwin.work;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;

/**
 * Class类对象的常用方法
 * @author wentao
 *
 */
public class FieldDemo {
    
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
	//Constructor的相关方法
		//获取类对象
		Class User = Class.forName("com.sofwin.work.User");
		User user1=new User(100,"xiaowang");
		//1.Field[] getFields()  --获取所以public修饰的成员变量
		Field[] fields = User.getFields();
		for (Field field : fields) {
			System.out.println(field.getName()); 
		}
	  //2.Field[] getDeclaredFields()  --获取所有的成员变量
		Field[] fields2 = User.getDeclaredFields();
		for (Field field2 : fields2) {
			System.out.println(field2.getName()); //id  name	
		}
		
		//3. Field  getDeclaredField(String name)  通过名称来获取成员变量对象
		  //NoSuchFieldException 异常
		Field field3 = User.getDeclaredField("id");
		System.out.println(field3.getName()); //id
		
		//4. Field  getField(String name)  通过名称来获取public修饰成员变量
//		Field field4 = User.getField("id");
//		System.out.println(field4.getName()); 
       
		//5.getName() 获取名称   getModifiers()  获取修饰符
		System.out.println(field3.getName());  //id
		System.out.println(field3.getModifiers());  //2
        
		//6.类型     get类型(Object obj)      obj对象的当前属性的值
		//这里如果是私有的成员变量要进行暴力破解
		field3.setAccessible(true);
		Object object = field3.get(user1);
		System.out.println(object);
		
		//7.类型     set类型(Object obj)      obj对象的当前属性的值
				 field3.set(user1,200);
				System.out.println(user1); //User [id=200, name=xiaowang]
 
				 
		
	}
}
	

 九、Method的常用API 

方法名返回结果描述
 getMethods()  Method[]获取所以public修饰的非构造方法
 getDeclaredMethods()  Method[] 获取所有的非构造方法
 getMethod(String name,Class<?>... parameterTypes)   Method 通过方法名和参数类型来获取public修饰非构造方法
 getDeclaredMethod(String name,Class<?>... parameterTypes)  Method 通过名称和参数类型来获取所有的非构造方法
invoke(Object obj, Object... args)    方法的返回结果相同 执行对象的方法
package com.sofwin.work;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;

/**
 * Class类对象的常用方法
 * @author wentao
 *
 */
public class MethodDemo {
    
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException, NoSuchFieldException {
	//Constructor的相关方法
		//获取类对象
		Class User = Class.forName("com.sofwin.work.User");
		User user1=new User(100,"xiaowang");
		//1.Method[] getMethods()  --获取所以public修饰的非构造方法
		Method[] method = User.getMethods();
		for (Method method1 : method) {
			System.out.println(method1.getName()); 
		}
	  //2.Method[] getDeclaredMethods()  --获取所有的非构造方法
		Method[] method2 = User.getDeclaredMethods();
		for (Method field3 : method2) {
			System.out.println(field3.getName()); 	
		}
		
		//3. Method  getMethod(String name, Class<?>... parameterTypes)     通过名称和参数类型来获取public非构造方法对象
		Method methodt = User.getMethod("setId",Integer.class);
		System.out.println(methodt.getName()); 
//		
		//4. Method getDeclaredMethod(String name, Class<?>... parameterTypes)     通过名称和参数类型来获取非构造方法对象
		Method methodt1 = User.getDeclaredMethod("setId",Integer.class);
		System.out.println(methodt1.getName()); 
       
		//5.getNa me() 获取名称   getModifiers()  获取修饰符  getReturnType()   获取返回值类型

		System.out.println(methodt1.getName());  
		System.out.println(methodt1.getModifiers());  
		System.out.println(methodt1.getReturnType());  
	
//		//6.类型     invoke(Object obj, Object... args)      执行对象的方法
		methodt1.invoke(user1, 300);
		System.out.println(user1);
// 
				 
		
	}
}
	

 十、Constructor的常用API 

方法名返回结果描述
  getConstructors()  Constructor[]获取所有public修饰的构造方法
 getDeclaredConstructors()  Constructor[]获取所有的构造方法
 getConstructor(Class<?>... parameterTypes)     Constructor 通过构造方法的参数类型来获去构造方法
 getDeclaredMethod(String name,Class<?>... parameterTypes)  Method 通过名称和参数类型来获取所有的非构造方法
 newInstance(Object... initargs)Object  这个是与Class类对象对应的  这个是通过参数来创建对象
package com.sofwin.work;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

/**
 * Class类对象的常用方法
 * @author wentao
 *
 */
public class ConstructorDemo {
    
	public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
	//Constructor的相关方法
		//获取类对象
		Class User = Class.forName("com.sofwin.work.User");
		
		//1.Constructor[] getConstructors()  --获取所以public修饰的构造方法
		Constructor[] constructors = User.getConstructors();
		for (Constructor constructor : constructors) {
			System.out.println(constructor.getName()); //com.sofwin.work.User
		}
		
		//2.Constructor[] getDeclaredConstructors()  --获取所以的构造方法
		Constructor[] constructors2 = User.getDeclaredConstructors();
		for (Constructor constructor : constructors2) {
			System.out.println(constructor.getName()); //com.sofwin.work.User
		}
		
		//3. Constructor  getConstructor(Class<?>... parameterTypes)  通过构造方法的参数类型来获去构造方法独享
		  //出现异常  --NoSuchMethodException
		Constructor constructor = User.getConstructor(Integer.class ,String.class);
		System.out.println(constructor); //public com.sofwin.work.User(java.lang.Integer,java.lang.String)
       
		//4.getName() 获取名称   getModifiers()  获取修饰符
		System.out.println(constructor.getName());  //com.sofwin.work.User
		System.out.println(constructor.getModifiers());  //1
		
		//5.Class[] getParameterTypes()   按照声明顺序返回构造方法的参数类型
		Class[] parameterTypes = constructor.getParameterTypes();
		for (Class class1 : parameterTypes) {
			System.out.println(class1);  //class java.lang.Integer  	class java.lang.String
		}
		
		//6.T newInstance(Object... initargs)  这个是与Class类对象对应的  这个是通过参数来创建对象
		Object newInstance = constructor.newInstance(1,"zhangsan");
		System.out.println(newInstance);  //User [id=1, name=zhangsan]
	   

	}

}

 十一、JDBC利用反射来封装工具类

package com.sofwin.work;

public class Account {
 private String name ;
 private Integer money;
public String getName() {
	return name;
}
public void setName(String name) {
	this.name = name;
}
public Integer getMoney() {
	return money;
}
public void setMoney(Integer money) {
	this.money = money;
}
@Override
public String toString() {
	return "Account [name=" + name + ", money=" + money + "]";
}
 

}

 

 

package com.sofwin.work;

import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import com.mysql.cj.xdevapi.PreparableStatement;

public class JdbcUtil {
    private static Connection conn;
    private static Properties props;
    private static Statement stmt;
    private static PreparedStatement pstmt;
	static {
		try {
			//创建Properties对象    实现动态的不是死编码
			props=new Properties();
			InputStream is=User.class.getClassLoader().getResourceAsStream("jdbc.properties");
			props.load(is);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}	
		//驱动加载只需要一次  因此加入到类代码块中就可以了
		try {
			Class.forName(props.getProperty("jdbc.driver"));
			
		} catch (ClassNotFoundException e) {
				e.printStackTrace();
		}
		
	}
	/**
	 * 获取Connection连接对象
	 * @return
	 * @throws SQLException
	 */
	public static Connection getConnection() throws SQLException {
		return DriverManager.getConnection(props.getProperty("jdbc.url"),props.getProperty("jdbc.username"),props.getProperty("jdbc.pwd"));
	}
   
	/**
	 * 静态
	 * @param sql
	 * @return
	 * @throws SQLException
	 */
	 public static List<Map>  executeQuery(String sql) throws SQLException {
		 List<Map> result=new ArrayList();
		 ResultSet rs =null;
		 try {
			conn=JdbcUtil.getConnection();
			 stmt = conn.createStatement();
			 rs = stmt.executeQuery(sql);
			 //获取ResultSet的源对象  
			 ResultSetMetaData metaData = rs.getMetaData();
			 //获取到列的数量
			 int columnCount=metaData.getColumnCount();
			 while(rs.next()) {
				 Map map =new HashMap();
			     for(int i=1;i<=columnCount;i++) {
			    	 String columnLabel = metaData.getColumnLabel(i);
			    	 Object obj=rs.getObject(columnLabel);
			    	map.put(columnLabel, obj); 		 
				 }
				 //添加进去
				 result.add(map);
			 }
			 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//关闭资源
			JdbcUtil.closeAll(conn, stmt, rs);
		}
		 return result;
	 }
	 
	 /**
	  * 动态sql语句
	  * @param sql
	  * @param parms
	  * @return
	  * @throws SQLException
	  */
	 public static List<Map>  executeQuery2(String sql,Object...parms) throws SQLException {
		 List<Map> result=new ArrayList();
		 ResultSet rs =null;
		 try {
			conn=JdbcUtil.getConnection();
			 pstmt =  conn.prepareStatement(sql);
			 //占位符赋值
			 if(parms!=null&&parms.length>0) {
				for(int i=0;i<parms.length;i++) {
					pstmt.setObject(i+1, parms[i]);
				}
			 }
			 rs = pstmt.executeQuery();
			 //获取ResultSet的源对象  
			 ResultSetMetaData metaData = rs.getMetaData();
			 //获取到列的数量
			 int columnCount=metaData.getColumnCount();
			 while(rs.next()) {
				 Map map =new HashMap();
			     for(int i=1;i<=columnCount;i++) {
			    	map.put(metaData.getColumnLabel(i), rs.getObject(i)); 		 
				 }
				 //添加进去
				 result.add(map);
			 }
			 
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//关闭资源
			JdbcUtil.closeAll(conn, pstmt, rs);
		}
		 return result;
	 }
	 
	 
	 /**
	  * 反射  更加复合面向对象的思想
	  * @param sql
	  *  @param obj  要封装的类对象
	  * @return
	  * @throws SQLException
	  */
	 public static <T> List<T>  executeQuery3(String sql,Class obj) throws SQLException {
		 List result=new ArrayList();
		 ResultSet rs =null;
		 try {
			 conn=JdbcUtil.getConnection();
			 stmt = conn.createStatement();
			 rs = stmt.executeQuery(sql);
			 //获取ResultSet的源对象  
			 ResultSetMetaData metaData = rs.getMetaData();
			 //获取到列的数量
			 int columnCount=metaData.getColumnCount();
			 while(rs.next()) {
				 //要封装的类型必须有无参的构造方法
				 Object map =obj.newInstance();
				 //属性对应列   我们这里规定属性名和列名是相同的
				 
			     for(int i=1;i<=columnCount;i++) {
			    	 //列名
			    	String columnLabel = metaData.getColumnLabel(i);
			    	//获取到成员变量的对象
			    	Field field=obj.getDeclaredField(columnLabel);	 
			        field.setAccessible(true);
			        field.set(map, rs.getObject(columnLabel));
				 }
				 //添加进去
				 result.add(map);
			 }
			 
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}finally {
			//关闭资源
			JdbcUtil.closeAll(conn, stmt, rs);
		}
		 return result;
	 }
	 
	 /**
	  * 关闭资源的方法
	  * @param conn
	  * @param stmt
	  * @param rs
	  * @throws SQLException
	  */
   public static void closeAll(Connection conn, Statement stmt,ResultSet rs) throws SQLException {
	   if(rs!=null) rs.close();
	   if(stmt!=null) stmt.close();
	   if(conn!=null) conn.close();
   }
}

  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值