最近学习java开始接触到了框架,突然觉得java反射很重要,因此在这里做了一些总结(参考园中大苞米大神的文章)

首先我们要认识一下Class:

一、Class类有什么用?

class类的实例表示java应用运行时的类(class ans enum)或接口(interface and annotation)(每个java类运行时都在JVM里表现为一个class对象,可通过类名.class,类型.getClass(),Class.forName("类名")等方法获取class对象)。数组同样也被映射为为class 对象的一个类,所有具有相同元素类型和维数的数组都共享该 Class 对象。基本类型boolean,byte,char,short,int,long,float,double和关键字void同样表现为 class  对象。

二、Class类的特征
    class类没有公有的构造方法,它由JVM自动调用(在new对象或者加载-classLoader时)

三、Class类是Reflection API中核心的类,他位于java.lang.Class

列出一些常用的方法。

- getClassLoader():返回该类的加载器

- forName(String className):返回与带有给定字符串名的类或接口相关联的 Class 对象

- getDeclaredAnnotations():返回直接存在于此元素上的所有注释

- getAnnotation(Class<A> annotationClass):如果存在该元素的指定类型的注释,则返回这些注释,否则返回 null。

- getAnnotations():返回此元素上存在的所有注释。

- getName() : 获得类的完整名字

- getFields() : 获得类的public类型的属性

- getDeclaredFields() : 获得类的所有属性

- getMethods() : 获得类的public类型的方法

- getDeclaredMethods() : 获得类的所有方法

- getMethod(String name, Class[] parameterTypes) : 获取类的特定方法(name参数指定方法名字,parameterTypes参数指定方法参数类型)

- getConstructors() : 获得类的public类型的构造方法

- getConstructor(Class[] parameterTypes) : 获得类的特定构造方法(parameterTypes参数指定构造方法的参数类型)

- newInstance() : 通过类的不带参数的构造方法创建这个类的一个对象

等等,具体可以参照API文档

初步知识了Class以后,我们看看

四、如何获取其对象class

获取某个类或某个对象所对应的Class对象的常用的3种方法

a) 使用Class类的静态方法forName:

Class.forName("java.lang.String");

b) 使用类的.class语法:

String.class;

c) 使用对象的getClass()方法(java.lang.Object类中的方法):

String s = "aa";

Class<?> clazz = s.getClass();

五、通过反射获取对象


创建一个PO类

package po;

public class User {
/**
* id
*/
private int id;
/**
* 年龄
*/
private int age;
/**
* 姓名
*/
private String name; /**
*
*/
public User() {
super();
}
/**
* @param id
* @param name
* @param age
*/
public User(int id, String name, int age) {
super();
this.id = id;
this.name = name;
this.age = age;
}
/**
* @return the age
*/
public int getAge() {
return age;
}
/**
* @return the id
*/
public int getId() {
return id;
}
/**
* @return the name
*/
public String getName() {
return name;
}
/**
* @param age the age to set
*/
public void setAge(int age) {
this.age = age;
}
/**
* @param id the id to set
*/
public void setId(int id) {
this.id = id;
} /**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}
public String toString() {
return "User [id=" + id + ", name=" + name + ", age=" + age + "]";
} }

大家都知道获得对象实例就是去new一个,其实就是调用对象的构造方法

这里将调用构造方法参数的不同分为两种类型:

a)调用无参数的构造方法:

1.调用Class对象的newInstance()方法:

@Test
public void test01() throws Exception{
Class<?> clazz=Class.forName("po.User");
User newInstance =(User)clazz.newInstance();
newInstance.setAge(24);
newInstance.setId(1001);
newInstance.setName("wangyang");
System.out.println(newInstance);
//User [id=1001, name=wangyang, age=24] }

2.调用Class对象的Constructor对象的newInstance()方法,传递一个空的Class对象数组作为参数:

@Test
public void test01() throws Exception{
Class<?> clazz=Class.forName("po.User");
Constructor user=clazz.getConstructor(null);
User u=(User) user.newInstance(null);
u.setAge(24);
u.setId(10);
u.setName("wangyang");
System.out.println(u);
//User [id=10, name=wangyang, age=24] }

b)调用有参数的构造方法:

调用Class对象的Constructor对象的newInstance()方法,传递一个可变长的Class对象数组作为参数

@Test
public void test01() throws Exception{
Class<?> clazz=Class.forName("po.User");
Constructor user=clazz.getConstructor(int.class,String.class,int.class);
Object newInstance = user.newInstance(24,"wangyang",24);
System.out.println(newInstance);
//User [id=24, name=wangyang, age=24]
}

3.再来试一试反射调用方法

@Test
public void test01() throws Exception{
Class<?> clazz=Class.forName("po.User");
Object newInstance = clazz.newInstance();
Method m=clazz.getMethod("setAge", int.class);
Method m2=clazz.getMethod("toString", null);
m.invoke(newInstance, 100);
System.out.println(m2.invoke(newInstance, null));
//User [id=0, name=null, age=100]
}

java_reflect_01的更多相关文章

随机推荐

  1. JVM上的随机数与熵池策略

    在apache-tomcat官方文档:如何让tomcat启动更快里面提到了一些启动时的优化项,其中一项是关于随机数生成时,采用的“熵源”(entropy source)的策略. 他提到tomcat7的 ...

  2. Linux企业级开发技术(3)——epoll企业级开发之epoll模型

    EPOLL事件有两种模型: Edge Triggered (ET)  边缘触发 只有数据到来,才触发,不管缓存区中是否还有数据. Level Triggered (LT)  水平触发 只要有数据都会触 ...

  3. 【转】 Android开发之EditText属性详解

    原文网址:http://blog.csdn.net/qq435757399/article/details/7947862 1.EditText输入的文字为密码形式的设置 (1)通过.xml里设置: ...

  4. bzoj 1602 [Usaco2008 Oct]牧场行走(LCA模板)

    1602: [Usaco2008 Oct]牧场行走 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 379  Solved: 216[Submit][Sta ...

  5. 浅谈二维RMQ

    针对一些二维区间最值问题,用一维RMQ来解决显然是不够的.所以,要改进算法.鉴于网上没有PASCAL版的RMQ标程与解析,所以小可在这里简单的讲一下. 核心思想和一维的一样,只是在计算区间时略有不同. ...

  6. Python Logging 模块研究

    背景在一个新的项目里面加入了日志功能,想自己写一个,但是一个偶然的机会,通过google发现Python内建了一个非常强大的日志(log)模块:l... 背景 在一个新的项目里面加入了日志功能,想自己 ...

  7. autoIT 自动化上传/下载文件图文详解【python selenium】

    情景: 在用selenium进行web页面自动化时,时不时会遇到上传附件的情况,常见的情况就是一个上传按钮,点击后弹出windows窗口,选择文件后上传,如下图1所示 图1 这种情况超出了seleni ...

  8. cocos2d_android开发简单游戏

    1)游戏图层设计: public class WellcomeLayer extends CCLayer { public WellcomeLayer() { this.setIsTouchEnabl ...

  9. Hadoop HDFS (3) JAVA訪问HDFS

    如今我们来深入了解一下Hadoop的FileSystem类. 这个类是用来跟Hadoop的文件系统进行交互的.尽管我们这里主要是针对HDFS.可是我们还是应该让我们的代码仅仅使用抽象类FileSyst ...

  10. [Angular 2] Exposing component properties to the template

    Showing you how you can expose properties on your Controller to access them using #refs inside of yo ...