学习笔记之 反射实例
来源:互联网 发布:unix环境高级编程第3版 编辑:程序博客网 时间:2024/06/06 14:48
一.Person类
1.1实体
public class Person {
private Stringname;
private int age;
public int num;
public static String country ="cn";
public Person() {
}
public Person(String name,int age) {
this.name = name;
this.age = age;
System.out.println("2个参数的构造函数");
}
private Person(String name) {
this.name = name;
}
public String getName() {
returnname;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
returnage;
}
public void setAge(int age) {
this.age = age;
}
public void eat() {
System.out.println("吃东西");
}
public void eat(String food) {
System.out.println("吃:" + food);
}
public static void play(String game) {
System.out.println("玩:" + game);
}
private void movie(String name) {
System.out.println("看:" + name);
}
@Override
public String toString() {
return"Person [name=" + name + ", age=" + age + ", num=" + num + "]";
}
}
二.反射测试
2.1 获取Person 类的字节码对象. Class
/*
* 获取Person类的字节码对象. Class
*/
@Test
public void testGetPersonClass() throws ClassNotFoundException {
// 方式一:类名.class
Class clazz = Person.class;
// 方式二:对象.getClass()
Person p = new Person();
Class clazz1 = p.getClass();
// 方式三: Class的静态方法forName加载指定的类的...
Class clazz2 = Class.forName("cn.itcast.gz.a_reflect.Person");
// 字节码文件只加载一次,所以是Class对象在内存中是唯一的.
System.out.println(clazz == clazz1);
}
2.2 获取Person 类的字节码信息,并分析
/**
* 获取Person类的字节码信息,并分析
*
* @throws ClassNotFoundException
* */
@Test
public void testGetPersonInfo() throws ClassNotFoundException {
Class clazz = Class.forName("cn.itcast.gz.a_reflect.Person");
// 获取类的类名 ->获取类的完整的名称...全限定名称(包名+类名)
String name = clazz.getName();
/**cn.itcast.gz.a_reflect.Person**/
// 获取类的简单名称只有类名.
String simpleName = clazz.getSimpleName();
/**Person**/
// 获取类的修饰符
// public ->1 default 0 abstract 1024
int modifiers = clazz.getModifiers();
/**1**/
}
2.3 获取类的成员变量
/**
* 获取类的成员变量
*
* @throwsClassNotFoundException
* @throws NoSuchFieldException
* @throws SecurityException
*
* 注意:虽然反射可以获取类中的成员变量,还是面向对象的基本的原则静态成员变量:随着的类的加载而加载.
* 通过反射机制,给静态的变量赋值和取值时,不需要传递对象,给类的成员取值和赋值.非静态成员:
* 创建对象,在对象的对内存中依赖于对象存在的.通过反射机制,该非静态的成员变量时,需要指定一个对象.给哪个对象的对象
* 赋值和取值吧...
*/
@Test
public void testGetFields() throws Exception {
Class clazz = Class.forName("cn.itcast.gz.a_reflect.Person");
Object p = clazz.newInstance();
/** Person [name=null, age=0,num=0] **/
// 获取类中的所有的公有的成员变量
Field[] fields = clazz.getFields();
for (Field field : fields) {
System.out.println(field);
}
/**
* public int cn.itcast.gz.a_reflect.Person.num ;
* public static java.lang.String cn.itcast.gz.a_reflect.Person.country;
*/
// 获取类中所有的成员变量(包括私有的)
Field[] declaredFields = clazz.getDeclaredFields();
for (Field field : declaredFields) {
System.out.println(field.getName());
}
/** name age num country **/
// 获取类中指定的成员变量...指定成员变量的名称
Field f = clazz.getField("num");
/**public int cn.itcast.gz.a_reflect.Person.num**/
// 给成员变量赋值
f.set(p, 100);
// 成员变量可以存储信息,取出信息...
System.out.println(f.get(p));
/**100**/
System.out.println(p);
/**Person [name=null, age=0, num=100]**/
// 获取类中指定的成员变量
Field f1 = clazz.getField("country");
/**public static java.lang.String cn.itcast.gz.a_reflect.Person.country**/
// 获取成员变量的值.
System.out.println(f1.get(null));
/**cn**/
f1.set(null,"us");
/**us**/
// 获取.私有的成员变量
Field f2 = clazz.getDeclaredField("name");
/**private java.lang.String cn.itcast.gz.a_reflect.Person.name**/
// 暴力反射 (打开权限)
f2.setAccessible(true);
// 赋值,取值.注意: name 是私有的成员变量... 无法直接赋值的
f2.set(p, "张三疯");
/**
* 张三疯
* Person [name=张三疯, age=0,num=100]
*/
}
2.4 获取类中的构造函数 Constructor 对象
/**
* 获取类中的构造函数 Constructor对象: 该对象提供了一个核心方法: newInstance();可以根据指定的构造函数,创建对象.
* 反射用在以后的框架中...配置文件.
*
* @throws Exception
*/
@Test
public void testConstructor() throws Exception {
Class clazz = Class.forName("cn.itcast.gz.a_reflect.Person");
// 获取所有的公有的构造函数...
Constructor[] constructors = clazz.getConstructors();
// 获取类中所有的构造函数(包含私有的)
Constructor[] declaredConstructors = clazz.getDeclaredConstructors();
for (Constructor constructor : declaredConstructors) {
System.out.println(constructor);
}
/**
* public cn.itcast.gz.a_reflect.Person()
* public cn.itcast.gz.a_reflect.Person(java.lang.String,int)
* private cn.itcast.gz.a_reflect.Person(java.lang.String)
*/
// 获取指定的构造函数...一个类中存在多个构造函数,是以重载的形式存在(函数名相同,参数列表不同).
Constructor c1 = clazz.getConstructor(String.class,int.class);
/**public cn.itcast.gz.a_reflect.Person(java.lang.String,int)**/
// 创建对象->获取的构造函数.该构造函数需要2个参数.
Person p = (Person) c1.newInstance("张无忌", 18);
/**Person [name=张无忌, age=18,num=0]**/
// 获取无参数的构造函数.
Constructor c2 = clazz.getConstructor(null);
/**public cn.itcast.gz.a_reflect.Person()**/
// 根据获取的无参数构造创建对象.
Person p1 = (Person) c2.newInstance(null);
/**Person [name=null, age=0, num=0]**/
// 普通创建对象方式...普通用法
Person person = new Person();
}
2.4.1 私有构造函数用法
/**
* 私有构造函数无法直接获取.需要特殊的方法. 注意: 破坏了面向对象封装的基本原则...不要随便使用...
*
* @throws Exception
*/
@Test
public void getPrivateCon() throws Exception {
Class clazz = Class.forName("cn.itcast.gz.a_reflect.Person");
// 获取私有的
Constructor c1 = clazz.getDeclaredConstructor(String.class);
/**private cn.itcast.gz.a_reflect.Person(java.lang.String)**/
// 创建对象.注意: 构造函数私有,所以使用时需要设置权限(暴力反射)
c1.setAccessible(true);
Object p = c1.newInstance("赵敏");
/**Person [name=赵敏, age=0,num=0]**/
}
2.5 获取类的方法.
/**
* 获取类的方法.
*
* @throws Exception
*/
@Test
public void testMehtod() throws Exception {
Class clazz = Class.forName("cn.itcast.gz.a_reflect.Person");
Object p = clazz.newInstance();
// 获取所有的公有方法,包含父类的.
Method[] methods = clazz.getMethods();
// 获取所有的构造函数.包含私有的.
Method[] declaredMethods = clazz.getDeclaredMethods();
// 获取指定的方法.
// 需要指定函数名,
Method m1 = clazz.getMethod("eat",null);
/**public void cn.itcast.gz.a_reflect.Person.eat()**/
// Method 对象的 invoke方法. 执行方法...
// 注意:获取的eat 方法是非静态的, 在Java中非静态的方法,必须依赖于对象调用的.
m1.invoke(p, null);
// 获取有参数的eat方法.
Method m2 = clazz.getMethod("eat", String.class);
m2.invoke(p, "馒头");
// 获取静态方法.
// 注意:执行静态方法时, 静态方法不需要创建对象就可以执行, 本例无需指定对象.
Method m3 = clazz.getMethod("play", String.class);
m3.invoke(null,"lol");
// 获取私有方法.
Method m4 = clazz.getDeclaredMethod("movie", String.class);
/**private void cn.itcast.gz.a_reflect.Person.movie(java.lang.String)**/
m4.setAccessible(true);
m4.invoke(p, "c老师");
/**
* public java.lang.String cn.itcast.gz.a_reflect.Person.toString()
* public java.lang.String cn.itcast.gz.a_reflect.Person.getName()
* public void cn.itcast.gz.a_reflect.Person.setName(java.lang.String)
* public void cn.itcast.gz.a_reflect.Person.eat() public void
* cn.itcast.gz.a_reflect.Person.eat(java.lang.String) public static
* void cn.itcast.gz.a_reflect.Person.play(java.lang.String) private
* void cn.itcast.gz.a_reflect.Person.movie(java.lang.String) publicint
* cn.itcast.gz.a_reflect.Person.getAge() public void
* cn.itcast.gz.a_reflect.Person.setAge(int) public void
* cn.itcast.gz.a_reflect.Person.eat()
*/
}
- 学习笔记之 反射实例
- Java学习笔记之反射
- Java学习笔记之反射
- javaSE学习笔记之反射
- java学习笔记之反射
- Java学习笔记之反射
- java学习笔记之反射
- Java学习笔记之反射
- Java SE学习笔记:反射、反射创建实例,反射调用方法
- 黑马程序员------java学习笔记之反射
- CSharp学习笔记之十三 反射
- Java学习笔记之反射机制初探
- 反射 学习笔记之动态加载类
- Android开发学习笔记之反射技术
- 黑马程序员Java学习笔记之反射
- Java学习之反射机制笔记--4
- Java学习笔记之反射(Reflection)
- Java学习笔记之反射(Reflection)
- [Bzoj1003][ZJOI2006]物流运输trans
- SurfaceView
- const经典例子小结
- 【Android】Frame Animation
- 第一次
- 学习笔记之 反射实例
- JQuery学习笔记(三)
- jQuery版QQ在线客服代码
- 判断ANDROID系统的版本号也即API Leve
- MySQL的create table as 与 like区别
- (剑指offer笔记)根据前序遍历和中序遍历重建二叉树
- poj 2125 最小割解决 "最小点权覆盖问题" +输出解(割边集)
- 使用repo下载google 的android4.4 源码,和编译.运行
- 类库项目