一、反射

反射:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意一个方法和属性;这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。

要想解剖一个类,必须先要获取到该类的字节码文件对象。而解剖使用的就是Class类中的方法.所以先要获取到每一个字节码文件对应的Class类型的对象。对于反射的操作实际上就是通过Class对象获取:
 *a、java.lang.reflect.Field:提供有关类或接口的单个字段的信息,以及对它的动态访问权限。反射的字段可能是一个类(静态)字段或实例字段。操作类的成员变量。
 *b、java.lang.reflect.Constructor<T>:操作类的够造函数。
 *c、java.lang.reflect.Method:操作类的方法。
在学习反射基础前先创建一个Person对象作为实例:
package com.jalja.org.base.relfect;

public class Person {
private String name;
int age;
public String address; public Person() {
} private Person(String name) {
this.name = name;
} Person(String name, int age) {
this.name = name;
this.age = age;
} public Person(String name, int age, String address) {
this.name = name;
this.age = age;
this.address = address;
} public void show() {
System.out.println("show");
} public void method(String s) {
System.out.println("method " + s);
} public String getString(String s, int i) {
return s + "---" + i;
} private void function() {
System.out.println("function");
} @Override
public String toString() {
return "Person [name=" + name + ", age=" + age + ", address=" + address
+ "]";
} }

二、获取类的Class对象

 1 public static void getClassObject() throws ClassNotFoundException{
2 //方式一:Object的getClass()方法
3 Person person1=new Person();
4 Person person2=new Person();
5 Class c1=person1.getClass();
6 Class c2=person2.getClass();
7 System.out.println(person1==person2);//false
8 System.out.println(c1==c2);//true 不管JVM内存中有多少个对象,对于字节码文件来说只有一份
9 //方式二:数据类型的静态class属性
10 Class c3=Person.class;
11 System.out.println(c1==c3);//true
12 //方式三:Class 类的静态方法
13 //public static Class<?> forName(String className)throws ClassNotFoundException
14 Class c4=Class.forName("com.jalja.org.base.relfect.Person");
15 System.out.println(c1==c4);//true
16 }

三、java.lang.reflect.Constructor<T>:对象并使用Constructor类。

1、获取Constructor对象

    //获取Class 对象所表示的类的构造方法
public static void getConstructorTest() throws Exception{
Class c4=Class.forName("com.jalja.org.base.relfect.Person");
//1、获取Class 对象所表示的类所有公共构造方法
//public Constructor<?>[] getConstructors() throws SecurityException
Constructor [] cs=c4.getConstructors();
//2、获取Class 对象所表示的类所有构造方法
//public Constructor<?>[] getDeclaredConstructors() throws SecurityException
Constructor[] cs2 =c4.getDeclaredConstructors();
//3、获取Class对象所表示类的指定指定公共构造方法, parameterTypes 参数是 Class 对象的一个数组 ,是指定数据类型的字节码
//public Constructor<T> getConstructor(Class<?>... parameterTypes);
Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
//获取 该 构造函数 public Person(String name, int age, String address)
Constructor cs4=c4.getConstructor(String.class,int.class,String.class);
//4、获取Clss对象所表示类指定的构造范法官 parameterTypes 参数是 Class 对象的一个数组,它按声明顺序标识构造方法的形参类型的字节码。
//public Constructor<T> getDeclaredConstructor(Class<?>... parameterTypes);
//获取该构造 函数 private Person(String name) 的Constructor对象
Constructor cs5=c4.getDeclaredConstructor(String.class); }

2、通过 Constructor 对象创建Class对象所表示类的实例

public static void createObject() throws Exception{
Class c4=Class.forName("com.jalja.org.base.relfect.Person");
//使用此 Constructor 对象表示的构造方法来创建该构造方法的声明类的新实例,并用指定的初始化参数初始化该实例
//public T newInstance(Object... initargs);
// Person person=new Person()
Constructor cs3=c4.getConstructor();//获取公共的无参构造方法的Constructor对象
Object obj=cs3.newInstance(); //Person person=new Person("jalja", 21, "北京");
Constructor cs4=c4.getConstructor(String.class,int.class,String.class);
Object obj1=cs4.newInstance("jalja",21,"北京");
System.out.println(obj1);//Person [name=jalja, age=21, address=北京] //实例化一个私有的构造函数 private Person(String name)
//控制java的访问检查
//public void setAccessible(boolean flag)
//将此对象的 accessible 标志设置为指示的布尔值。值为 true 则指示反射的对象在使用时应该取消 Java 语言访问检查。
//值为 false 则指示反射的对象应该实施 Java 语言访问检查。
Constructor cs5=c4.getDeclaredConstructor(String.class);
cs5.setAccessible(true);
Object obj2=cs5.newInstance("张三丰");
System.out.println(obj2);//Person [name=张三丰, age=0, address=null]
}

四、java.lang.reflect.Field

1、获取Field对象

//获取Class类的Field对象
public static void getFieldTest() throws Exception{
Class cs=Class.forName("com.jalja.org.base.relfect.Person");
//1、public Field[] getFields() throws SecurityException
//获取Class 对象所表示的类或接口的所有可访问公共(public修饰的)字段
Field [] fs=cs.getFields();
//2、public Field[] getDeclaredFields() throws SecurityException
// 获取Class 对象所表示的类或接口所声明的所有字段。包括公共、保护、默认(包)访问和私有字段,但不包括继承的字段
Field [] fs1=cs.getDeclaredFields();
//3、public Field getField(String name)throws NoSuchFieldException, SecurityException;
//获取Class 对象所表示的类或接口的指定公共成员(public修饰)字段。name 参数是一个 String,用于指定所需字段的简称
Field fs2=cs.getField("address");
//public Field getDeclaredField(String name) throws NoSuchFieldException,SecurityException
//获取 Class 对象所表示的类或接口的指定已声明字段。name 参数是一个 String,它指定所需字段的简称
Field fs3=cs.getDeclaredField("name");
System.out.println(fs3);
}

2、通过Field对象对指定类属性赋值

//使用 Field对象
public static void createVarValue() throws Exception{
Class cs=Class.forName("com.jalja.org.base.relfect.Person");
Object obj=cs.getConstructor().newInstance();
Field addressField=cs.getField("address");
//public void set(Object obj, Object value);
//将指定对象变量上此 Field 对象表示的字段设置为指定的新值。如果底层字段的类型为基本类型,则对新值进行自动解包
//obj - 应该修改其字段的对象 value - 正被修改的 obj 的字段的新值
addressField.set(obj, "北京");
System.out.println(obj); //Person [name=null, age=0, address=北京] //对非public修饰的变量操作
Field nameField=cs.getDeclaredField("name");
//控制java的访问检查
nameField.setAccessible(true);
nameField.set(obj, "张三丰");
System.out.println(obj);//Person [name=张三丰, age=0, address=北京]
}

五、java.lang.reflect.Method

1、获取Method对象

//获取Method对象
public static void getMethodTest() throws Exception{
Class cs=Class.forName("com.jalja.org.base.relfect.Person");
//1、public Method[] getMethods() throws SecurityException
//获取Class 对象所表示的类或接口(包括那些由该类或接口声明的以及从超类和超接口继承的那些的类或接口)的公共 member 方法。
Method [] m1=cs.getMethods();
//2、public Method[] getDeclaredMethods() throws SecurityException
//获取Class 对象表示的类或接口声明的所有方法,包括公共、保护、默认(包)访问和私有方法,但不包括继承的方法
Method [] m2=cs.getDeclaredMethods();
//3、public Method getMethod(String name, Class<?>... parameterTypes)throws NoSuchMethodException, SecurityException;
// 获取Class 对象所表示的类或接口的指定公共成员方法。name 参数是一个 String,用于指定所需方法的简称。parameterTypes 参数是按声明顺序标识该方法形参类型的 Class 对象的一个数组
Method m3=cs.getMethod("show");//无参的方法
Method m4=cs.getMethod("method",String.class);//带参的方法
//public Method getDeclaredMethod(String name, Class<?>... parameterTypes)throws NoSuchMethodException,SecurityException
// Class 对象所表示的类或接口的指定已声明方法。name 参数是一个 String,它指定所需方法的简称,parameterTypes 参数是 Class 对象的一个数组
Method m5=cs.getDeclaredMethod("function");//无参的方法
System.out.println(m5);
}

2、通过Method对象调用指定类的方法

// Method对象的使用
public static void createMethod() throws Exception{
Class cs=Class.forName("com.jalja.org.base.relfect.Person");
Object obj=cs.getConstructor().newInstance();
Method m3=cs.getMethod("show");//无参的方法
//public Object invoke(Object obj,Object... args)
//对带有指定参数的指定对象调用由此 Method 对象表示的底层方法 obj - 从中调用底层方法的对象 args - 用于方法调用的参数
m3.invoke(obj);
//对带参方法的操作
Method m4=cs.getMethod("method",String.class);//带参的方法
m4.invoke(obj,"北京");
//对有返回值得方法操作
Method m6=cs.getMethod("getString",String.class,int.class);//带参的方法
Object str=m6.invoke(obj,"北京",200);
System.out.println(str);
//对私有无参方法的操作
Method m5=cs.getDeclaredMethod("function");
m5.setAccessible(true);
m5.invoke(obj);
}

六、反射操作注解

@ClassAnnotation("tb_person")
public class Person {
@FieldAnnotation(name="table_name",length=32,type="varchar")
private String name;
@FieldAnnotation(name="table_age",length=3,type="int")
private int age;
@FieldAnnotation(name="table_address",length=32,type="varchar")
public String address;
  ....get;
  ....set;
}
//注解类
@Target(value={ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldAnnotation {
String name();
int length();
String type();
}
//注解类
@Target(value={ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface ClassAnnotation {
String value();
}
    //Annotation
public static void createAnnotation() throws Exception{
Class cs=Class.forName("com.jalja.org.base.relfect.Person");
//获取该类的所有注解
Annotation[] as= cs.getAnnotations();
//获取该类指定类型的注解 //@com.jalja.org.base.relfect.ClassAnnotation(value=tb_person)
ClassAnnotation at=(ClassAnnotation) cs.getAnnotation(ClassAnnotation.class);
//获取该注解设置的值
String an_value=at.value();//tb_person //获取类 name属性(Field)的注解类型
FieldAnnotation fieldName=cs.getDeclaredField("name").getAnnotation(FieldAnnotation.class);
//获取注解值 #table_name--32--varchar
System.out.println(fieldName.name()+"--"+fieldName.length()+"--"+fieldName.type());
}

java反射基础知识(一)的更多相关文章

  1. java反射基础知识(五)反射应用实践

    详解Java反射各种应用   Java除了给我们提供在编译期得到类的各种信息之外,还通过反射让我们可以在运行期间得到类的各种信息.通过反射获取类的信息,得到类的信息之后,就可以获取以下相关内容: Cl ...

  2. java反射基础知识(四)反射应用实践

    反射基础 p.s: 本文需要读者对反射机制的API有一定程度的了解,如果之前没有接触过的话,建议先看一下官方文档的Quick Start. 在应用反射机制之前,首先我们先来看一下如何获取一个对象对应的 ...

  3. java反射基础知识(三)

    原文地址:http://tutorials.jenkov.com/java-reflection/index.html http://www.cnblogs.com/penghongwei/p/329 ...

  4. java反射基础知识(二)

    1. 了解 Java 中的反射 1.1 什么是 Java 的反射 Java 反射是可以让我们在运行时获取类的函数.属性.父类.接口等 Class 内部信息的机制.通过反射还可以让我们在运行期实例化对象 ...

  5. Java反射基础知识

    反射机制就是可以把一个类,类的成员(属性.方法)当成一个对象来操作,也就是说,类,类的成员,我们在运行的时候可以动态的去操作它们. 所有的Java类都继承了Object类,在Object类中定义了一个 ...

  6. 什么才是java的基础知识?

    近日里,很多人邀请我回答各种j2ee开发的初级问题,我无一都强调java初学者要先扎实自己的基础知识,那什么才是java的基础知识?又怎么样才算掌握了java的基础知识呢?这个问题还真值得仔细思考. ...

  7. Java 多线程——基础知识

    java 多线程 目录: Java 多线程——基础知识 Java 多线程 —— synchronized关键字 java 多线程——一个定时调度的例子 java 多线程——quartz 定时调度的例子 ...

  8. java必备基础知识(一)

    学习的一点建议: 每一门语言的学习都要从基础知识开始,学习是一个过程,"万丈高楼平地起",没有一个好的地基,想必再豪华的高楼大厦终究有一天会倒塌.因此,我们学习知识也要打牢根基,厚 ...

  9. java部分基础知识整理----百度脑图版

    近期发现,通过百度脑图可以很好的归纳总结和整理知识点,本着学习和复习的目的,梳理了一下java部分的知识点,不定期更新,若有不恰之处,请指正,谢谢! 脑图链接如下:java部分基础知识整理----百度 ...

随机推荐

  1. pl/sql 实例精解 08

    1: EXCEPTION 2: WHEN EXCEPTION_NAME THEN 3: ERROR-PROCESSING STATEMENTS; 写在 begin 与 end 的之间的处理异常块. 常 ...

  2. jsp有哪些内置对象?作用分别是什么?(至少三个)

    jsp有哪些内置对象?作用分别是什么?(至少三个) 解答: 1)request表示HttpServletRequest对象.它包含了有关浏览器请求的信息,并且提供了几个用于获取cookie, head ...

  3. jQery使网页在显示器上居中显示适用于任何分辨率

    这篇文章主要介绍了jQery使网页在任何分辨率的显示器上居中显示的方法,需要的朋友可以参考下 检测屏幕宽度,并设置为id为frame的div宽度, 根据自己网页的最大宽度来调节,小demo最大宽度为1 ...

  4. Page_ClientValidate 用法

    JS script function ConfirmMe(){   return confirm("Do you want to proceed?");} ASPX <asp ...

  5. mybatis 处理 mysql 表中的 text类型的 字段

    在mysql 中 text类型的字段: service_detail text NULL 服务描述   . 对应java文件中 model 中的 String:  private String ser ...

  6. 五月的仓颉大神写的 三年java程序员面试感悟 值得分享给大家

    感谢 五月的仓颉  的这篇文章 , 让我重新认识到自己身上的不足之处 .  原文地址http://www.cnblogs.com/xrq730/p/5260294.html,转载请注明出处,谢谢! 前 ...

  7. JS循环语句的理解

    循环语句就是让程序重复性去做某些工作 最常见的就是for循环 那它的写法都有哪些呢? 1.必须要有初始值 2.要有条件判断 3.状态的改变 4.循环体 一定要控制循环多少次结束,否则就变成了死循环,消 ...

  8. 【BZOJ4676】Xor-Mul棋盘 拆位+状压DP

    [BZOJ4676]Xor-Mul棋盘 Description 一个n*m的棋盘,左上角为(1,1),右下角为(n,m).相邻的2点之间有连边(如下图中实线)特殊地,(1,i)与(n,i)也连有一条边 ...

  9. 【BZOJ4145】[AMPPZ2014]The Prices 状压DP

    [BZOJ4145][AMPPZ2014]The Prices Description 你要购买m种物品各一件,一共有n家商店,你到第i家商店的路费为d[i],在第i家商店购买第j种物品的费用为c[i ...

  10. Android编译系统入门(一)

    做过Android平台开发的朋友对make,mm或make clean命令应该很熟悉,但也许大家只是熟知这些命令的作用却不知道这些命令底下有些什么原理?那么今天我就带着大家推开Android编译系统的 ...