java反射基础知识(一)

时间:2022-02-16 02:11:17

一、反射

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

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

二、获取类的Class对象

java反射基础知识(一)
 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反射基础知识(一)

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

1、获取Constructor对象

java反射基础知识(一)
    //获取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); }
java反射基础知识(一)

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

java反射基础知识(一)
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反射基础知识(一)

四、java.lang.reflect.Field

1、获取Field对象

java反射基础知识(一)
//获取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);
}
java反射基础知识(一)

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

java反射基础知识(一)
//使用 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反射基础知识(一)

五、java.lang.reflect.Method

1、获取Method对象

java反射基础知识(一)
//获取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);
}
java反射基础知识(一)

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

java反射基础知识(一)
// 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);
}
java反射基础知识(一)

六、反射操作注解

java反射基础知识(一)
@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;
}
java反射基础知识(一)
java反射基础知识(一)
//注解类
@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();
}
java反射基础知识(一)
java反射基础知识(一)
    //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. python基础-生成随机字符串方法

    python解释器示例 >>> import uuid >>> uuid.uuid1() UUID('ae6822e6-c976-11e6-82e0-0090f5f ...

  2. ytu 1980&colon;小鼠迷宫问题(DFS 深度优先搜索)

     小鼠迷宫问题 Time Limit: 2 Sec  Memory Limit: 64 MB Submit: 1  Solved: 1 [Submit][Status][Web Board] Desc ...

  3. oracle在线重定义表

    在一个高可用系统中,如果需要改变一个表的定义是一件比较棘手的问题,尤其是对于7×24系统.Oracle提供的基本语法基本可以满足一般性修改,但是对于把普通堆表改为分区表,把索引组织表修改为堆表等操作就 ...

  4. 补充:sql server 中的相关查询、case函数

    相关查询(在同一个表中) 相关查询类似子查询,但是又不同于子查询:子查询中的子条件可以单独查出数据,但是相关查询的子条件不能查处数据.(可以理解成C#中for的穷举法,第一个for走一个,第二个for ...

  5. 【形式化方法:VDM&plus;&plus;系列】3&period;基于VDM&plus;&plus;的图书管理系统需求定义

    接前文:http://www.cnblogs.com/Kassadin/p/4091040.html 1.Before We Start: 在开始图书管理系统需求定义之前,需要先进行一些说明. 1.1 ...

  6. Div与table的区别

    1:速度和加载方式方面的区别 div 和 table 的差异不是速度,而是加载方式,速度只能是指网络速度,如果速度足够快,是没有差异的: div 的加载方式是即读即加载,遇到 <div> ...

  7. WPF 图片浏览 伪3D效果

    原文:WPF 图片浏览 伪3D效果 首先上效果图: 因项目要求,需要把图片以"好看"."炫"的效果展示出来,特地研究了一下WPF关于3D方面的制作,奈何最终成果 ...

  8. Android ADB命令 adb devices 出现error:protocol fault &lpar;no status&rpar;

    问题背景:安装apk是报error:protocol fault<no status>或error:device not found手机驱动有问题 出现的问题如下:adb devices ...

  9. &lbrack;CSAcademy&rsqb;Virus on a Tree

    [CSAcademy]Virus on a Tree 题目大意: 给你一棵\(n(n\le10^5)\)个点的树,一开始点\(1\)有病毒,可以沿着边扩散.你可以事先切掉若干条边,使得病毒扩散不超过\ ...

  10. python3&period;6编程第一课画个五角星

    使用的是海龟图库  turtle import turtle turtle.forward(100) turtle.right(144) turtle.forward(100) turtle.righ ...