反射和类对象
当一个类被java虚拟机加载,那么它会创建一个类对象。每一个类都有并且只有一个类对象。类对象保
存了类的信息。一个类的类对象是对这个类的信息的描述。这个类对象的类型是java.lang.Class。
}
package itstar;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
interface I1 {
void print();
}
public class Test3 {
public static void main(String[] args) {
I1 i1 = () -> {
for (int i = 0; i < 10; i++) {
System.out.print("*");
}
};
i1.print();
// 定时器,用于执行定时任务
// 1000毫秒后,通知监听器,并且传递事件对象
// Timer t = new Timer(1000, new ActionListener() {
//
// @Override
// public void actionPerformed(ActionEvent e) {
// System.out.println(e)
// }
// });
// t.start();
//如果方法只有一个参数,并且这个参数的类型可以推导出,那么就可以忽略小括号
Timer t = new Timer(1000, e -> System.out.println(e));
t.start();
try {
Thread.sleep(5000);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
}
JAVA反射机制是在运行状态中,对于任意一个实体类,都能够知道这个类的所有属性和方法;对于任意
一个对象,都能够调用它的任意方法和属性;这种动态获取信息以及动态调用对象方法的功能称为java
语言的反射机制。
获取类对象的方式:
package itstar;
class Student{
private String name;
private int age;
public Student(String name, int age) {
super();
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
public class Test4 {
public static void main(String[] args) throws ClassNotFoundException {
//获取Student类的类对象
//1,类名.class
Class c1 = Student.class;
System.out.println(c1);
//2,使用继承于Object类的实例方法getClass
Student s = new Student("张三", 20);
Class c2 = s.getClass();
//3,使用Class的静态方法Class.forName()
Class c3 = Class.forName("itstar.Student");
System.out.println(c1 == c2);
System.out.println(c2 == c3);
//接口也有类对象
Class c4 = Comparable.class;
System.out.println(c4);
//基本类型也有类对象
Class c5 = int.class;
System.out.println(c5);
Class c6 = Integer.class;
System.out.println(c5 == c6);//false
利用反射分析类
类对象存储了类的信息,因此可以使用类对象来分析类。
//数组也有类对象
Class c7 = int[].class;
System.out.println(c7);
//这些类对象是为了服务于反射
//java中的所有类型(基本类型,引用类型(类,接口,数组))都有类对象
//类对象包含了类型的信息
}
}
package itstar;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Test5 {
public static void main(String[] args) throws ClassNotFoundException,
NoSuchMethodException, SecurityException, NoSuchFieldException {
String className = "java.lang.String";
// 加载类并获取String类的类对象
Class c = Class.forName(className);
// 获取父类的类对象
Class superC = c.getSuperclass();
// 获取父类的类名
System.out.println(superC.getName());
System.out.println("***********************");
// 获取实现了哪些接口
Class[] ifs = c.getInterfaces();
for (Class i : ifs) {
System.out.println(i);
}
System.out.println("***********************");
// 获取声明的构造器
Constructor[] cs = c.getDeclaredConstructors();
for (Constructor csr : cs) {
System.out.println(csr);
}
System.out.println("***********************");
// 获取参数为char[]的构造器
Constructor con1 = c.getDeclaredConstructor(char[].class);
System.out.println(con1);
// 获取参数为byte[],int,int的构造器
利用反射分析对象
获取对象的属性值
Constructor con2 = c.getDeclaredConstructor(byte[].class, int.class,
int.class);
System.out.println(con2);
System.out.println("***********************");
// 获取声明的属性
Field[] fields = c.getDeclaredFields();
for (Field field : fields) {
System.out.println(field);
}
// 获取某一个属性
Field hashField = c.getDeclaredField("hash");
System.out.println(hashField);
System.out.println("***********************");
// 获取声明的方法
Method[] methods = c.getDeclaredMethods();
for (Method method : methods) {
System.out.println(method);
}
// 获取某一个方法
Method indexOfMethod = c.getDeclaredMethod("indexOf", int.class,
int.class);
System.out.println(indexOfMethod);
}
}
package itstar;
import java.lang.reflect.Field;
public class Test6 {
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, IllegalArgumentException, IllegalAccessException
{
Student s1 = new Student("张三", 20);
Student s2 = new Student("李四", 21);
Class c = Student.class;
// 获取Student类中的name属性
Field nameField = c.getDeclaredField("name");
// 设置Student类中的name属性的访问权限
// 使Student类中name属性可以被反射获取
nameField.setAccessible(true);
调用对象的方法
// 获取s1对象中的name属性值
String s1NameValue = (String) nameField.get(s1);
System.out.println(s1NameValue);
// 获取s2对象中的name属性值
String s2NameValue = (String) nameField.get(s2);
System.out.println(s2NameValue);
// 获取Student类中的age属性
Field ageField = c.getDeclaredField("age");
// 设置Student类中的age属性的访问权限
// 使Student类中age属性可以被反射获取
ageField.setAccessible(true);
// 获取s1对象中的age属性
int s1AgeValue = (int) ageField.get(s1);
System.out.println(s1AgeValue);
//获取s2对象中的age属性
int s2AgeValue = (int) ageField.get(s2);
System.out.println(s2AgeValue);
}
}
package itstar;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Test7 {
public static void main(String[] args) throws NoSuchMethodException,
SecurityException, IllegalAccessException,
IllegalArgumentException, InvocationTargetException {
Student s1 = new Student("张三", 20);
Student s2 = new Student("李四", 21);
Class c = Student.class;
// 获取Student类的setName方法
Method setNameMethod = c.getDeclaredMethod("setName", String.class);
// 在s1对象上调用setName方法
setNameMethod.invoke(s1, "张三丰");
// 获取Student类的getName方法
Method getNameMethod = c.getDeclaredMethod("getName");
// 在s1对象上调用getName方法
String s1NameValue = (String) getNameMethod.invoke(s1);
System.out.println(s1NameValue);
}
创建对象
反射的应用
}
package itstar;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;
public class Test8 {
public static void main(String[] args) throws InstantiationException,
IllegalAccessException, NoSuchMethodException, SecurityException,
IllegalArgumentException, InvocationTargetException {
Class c = Student.class;
//调用无参构造器来创建一个Student类的实例
Student s1 = (Student)c.newInstance();
//获取Student类的参数类型为String,int的有参构造器
Constructor con = c.getDeclaredConstructor(String.class, int.class);
//调用构造器来创建对象
Student s2 = (Student)con.newInstance("张三", 20);
System.out.println(s2.getName());
System.out.println(s2.getAge());
}
}
package itstar;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
//实体类,对应数据库中的student表
//实体类的每个实例对应student表中的一行记录
class Student {
private int sid;
private String sname;
private int sage;
private String sgender;
private int cid;
public Student() {
super();
}
public int getSid() {
return sid;
}
public void setSid(int sid) {
this.sid = sid;
}
public String getSname() {
return sname;
}
public void setSname(String sname) {
this.sname = sname;
}
public int getSage() {
return sage;
}
public void setSage(int sage) {
this.sage = sage;
}
public String getSgender() {
return sgender;
}
public void setSgender(String sgender) {
this.sgender = sgender;
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", sage=" + sage
+ ", sgender=" + sgender + ", cid=" + cid + "]";
}
}
// 实体类,对应数据库中clazz表
class Clazz {
private int cid;
private String cname;
private String tname;
public Clazz() {
super();
}
public int getCid() {
return cid;
}
public void setCid(int cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getTname() {
return tname;
}
public void setTname(String tname) {
this.tname = tname;
}
@Override
public String toString() {
return "Clazz [cid=" + cid + ", cname=" + cname + ", tname=" + tname
+ "]";
}
}
public class Test9 {
// 查询student表的所有数据
public static List<Student> queryStudentList() {
// list保存整个表的数据
List<Student> list = new ArrayList<Student>();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 数据库连接url,用于配置参数:主机名,端口,数据库名称,编码格式
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8";
// 用户名
String username = "root";
String password = "root";
Connection con = null;
Statement sta = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(url, username, password);
sta = con.createStatement();
rs = sta.executeQuery("select * from student");
while (rs.next()) {
int sid = rs.getInt("sid");
String sname = rs.getString("sname");
int sage = rs.getInt("sage");
String sgender = rs.getString("sgender");
int cid = rs.getInt("cid");
// 创建一个对象来保存student表中的一行数据
Student s = new Student();
s.setSid(sid);
s.setSname(sname);
s.setSage(sage);
s.setSgender(sgender);
s.setCid(cid);
// 将对象加入集合中
list.add(s);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (sta != null) {
try {
sta.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
// 查询clazz表的所有数据
public static List<Clazz> queryClazzList() {
// list保存整个表的数据
List<Clazz> list = new ArrayList<Clazz>();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 数据库连接url,用于配置参数:主机名,端口,数据库名称,编码格式
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8";
// 用户名
String username = "root";
String password = "root";
Connection con = null;
Statement sta = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(url, username, password);
sta = con.createStatement();
rs = sta.executeQuery("select * from clazz");
while (rs.next()) {
int cid = rs.getInt("cid");
String cname = rs.getString("cname");
String tname = rs.getString("tname");
// 创建一个对象来保存student表中的一行数据
Clazz c = new Clazz();
c.setCid(cid);
c.setCname(cname);
c.setTname(tname);
// 将对象加入集合中
list.add(c);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (sta != null) {
try {
sta.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
// 能查询所有表的数据,通用方法
public static <T> List<T> queryForList(String sql, Class<T> c)
throws NoSuchFieldException, SecurityException,
InstantiationException, IllegalAccessException {
// list保存整个表的数据
List<T> list = new ArrayList<T>();
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
// 数据库连接url,用于配置参数:主机名,端口,数据库名称,编码格式
String url = "jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8";
// 用户名
String username = "root";
String password = "root";
Connection con = null;
Statement sta = null;
ResultSet rs = null;
try {
con = DriverManager.getConnection(url, username, password);
sta = con.createStatement();
rs = sta.executeQuery(sql);
while (rs.next()) {
// 反射来创建对象
T obj = c.newInstance();
// 获取结果集的元数据,元数据就是对数据的说明
ResultSetMetaData meta = rs.getMetaData();
// 获取结果集中的列数
int columnCount = meta.getColumnCount();
for (int i = 0; i < columnCount; i++) {
// 根据列的索引获取列名,数据库中的列索引从1开始
String columnName = meta.getColumnName(i + 1);
// 通过列名获取列值
Object columnValue = rs.getObject(columnName);
// 获取对应的属性
Field field = c.getDeclaredField(columnName);
// 设置访问权限
field.setAccessible(true);
// 将列值放入到对象的属性中
field.set(obj, columnValue);
}
// 将对象加入集合中
list.add(obj);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (sta != null) {
try {
sta.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return list;
}
public static void main(String[] args) throws NoSuchFieldException,
SecurityException, InstantiationException, IllegalAccessException {
List<Student> list1 = queryForList("select * from student",
Student.class);
for (Student student : list1) {
System.out.println(student);
}
List<Clazz> list2 = queryForList("select * from clazz", Clazz.class);
for (Clazz clazz : list2) {
System.out.println(clazz);
}
}
}