反射

反射和类对象

当一个类被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);

}

}

}

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,809评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,189评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 167,290评论 0 359
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,399评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,425评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,116评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,710评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,629评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,155评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,261评论 3 339
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,399评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 36,068评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,758评论 3 332
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,252评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,381评论 1 271
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,747评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,402评论 2 358

推荐阅读更多精彩内容