一、反射

反射: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. hdu1695 GCD 莫比乌斯反演做法+枚举除法的取值 (5,7),(7,5)看做同一对

    /** 题目:hdu1695 GCD 链接:http://acm.hdu.edu.cn/status.php 题意:对于给出的 n 个询问,每次求有多少个数对 (x,y) , 满足 a ≤ x ≤ b ...

  2. SSH初体验系列--Hibernate--1--环境配置及demo

    最近在学hibernate,常见的教程都是搭配mysql,因为公司本地电脑用的是pg,所以就尝试着做个pg的小demo. 自己也是边学边写,只当是加深印象.话不多说,直接开始; 一) 准备工作; 1) ...

  3. CI 跳转

    redirect('home/play/index');

  4. SQLServerException:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败。

    一.问题描述: 1.连接数据库时抛出的异常: com.microsoft.sqlserver.jdbc.SQLServerException: 通过端口 1433 连接到主机 localhost 的 ...

  5. (转)Apache Mina网络框架

    转自1:整体结构分析 http://www.cnblogs.com/xuekyo/archive/2013/03/06/2945826.html 转自2:详细源码分析 http://www.cnblo ...

  6. (转)git使用教程

    git基础使用:http://geek.csdn.net/news/detail/77455 github介绍:http://stormzhang.com/github/2016/05/25/lear ...

  7. 卡夫卡(kafka)

    1.Kafka独特设计在什么地方?2.Kafka如何搭建及创建topic.发送消息.消费消息?3.如何书写Kafka程序?4.数据传输的事务定义有哪三种?5.Kafka判断一个节点是否活着有哪两个条件 ...

  8. 搭建一个SSM框架

    刚好学完springMVC,mybatis简单的组合,总结一下 1.创建一个maven项目,引入jar包 一共这么多,除了oracle jar包是我手动添加到lib里,其他都是通过pom.xml引入的 ...

  9. poj 1322 Chocolate (概率dp)

    ///有c种不同颜色的巧克力.一个个的取.当发现有同样的颜色的就吃掉.去了n个后.到最后还剩m个的概率 ///dp[i][j]表示取了i个还剩j个的概率 ///当m+n为奇时,概率为0 # inclu ...

  10. MVC Model验证疑难杂症

    Q1:有验证但是还是能进入控制器(Controller) 排查之后发现js报错:VM109:1 Uncaught SyntaxError: Unexpected token u in JSON at ...