1反射机制是啥?

反射是运行中的程序检查自己和软件运行环境的能力,它可以根据它发现的进行改变。通俗的讲就是反射可以在运行时根据指定的类名获得类的信息。

2反射机制有啥用?

Reflection(反射)是被视为动态语言的关键反射机制使程序在执行期间借助于reflection API
取得任何类的内部信息,并能直接操作任意对象的内部属性和方法
java反射机制提供的功能
在运行时判断任意一个对象所属的类
在运行时构造任意一个类的对象
在运行时判断任意一个类所具有的成员变量和方法
在运行时调用任意一个对象的成员变量和方法
生成动态代理

3反射相关的api:

java.lang.Class
java.lang.reflect.Method
java.lang.reflect.Field
java.lang.reflect.Constructor

4反射机制实现的过程:

1.创建Class的实例

1.1过程:源文件经过编译(javac.exe)以后,得到一个或多个.class文件。.class文件经过运行(java.exe)这步,

就需要进行类的加载(通过JVM的类的加载器),记载到内存中的缓存。每一个放入缓存中的.class文件就是一个Class的实例!

1.2 Class的一个对象,对应着一个运行时类。相当于一个运行时类本身充当了Class的一个实例。

1.3 java.lang.Class是反射的源头。  接下来涉及到反射的类都在java.lang.reflect子包下。如:Field  Method Constructor  Type Package..

当通过Class的实例调用getMethods() --->Method , getConstructors() ---->Constructor

1.4实例化Class的方法(三种):

// 1.调用运行时类的.class属性

Class clazz1 = Person.class;

System.out.println(clazz1);

 

Class clazz2 = Creator.class;

System.out.println(clazz2);

// 2.通过运行时类的对象,调用其getClass()方法

Person p = new Person();

Class clazz3 = p.getClass();

System.out.println(clazz3);

// 3.调用Class的静态方法forName(String className)。此方法报ClassNotFoundException

String className = "com.atguigu.java.Person";

Class clazz4 = Class.forName(className);

System.out.println(clazz4);

2.有了Class实例以后,可以做什么?应用一:可以创建对应的运行时类的对象(重点)

//获取运行时类的对象:方法一

@Test

public void test1() throws Exception{

Class clazz = Class.forName("com.atguigu.review.Animal");

Object obj = clazz.newInstance();//new Instance时调用运行时类的空参构造器

//

Animal a = (Animal)obj;

System.out.println(a);

}

//调用指定的构造器创建运行时类的对象

@Test

public void test2() throws Exception{

Class clazz = Animal.class;

Constructor cons = clazz.getDeclaredConstructor(String.class,int.class);

cons.setAccessible(true);

Animal a = (Animal)cons.newInstance("Tom",10);

System.out.println(a);

}

3.有了Class实例以后,可以做什么?应用二:获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。

如:Method[] m1 = clazz.getMethods() :获取到对应的运行时类中声明的权限为public的方法(包含其父类中的声明的public)

Method[] m2 = clazz.getDeclaredMethods():获取到对应的运行时类中声明的所有的方法(①任何权限修饰符修饰的都能获取②不含父类中的)

4.有了Class实例以后,可以做什么?应用三:调用对应的运行时类中指定的结构(某个指定的属性、方法、构造器)

//调用指定属性

@Test

public void test3() throws Exception{

Class clazz = Class.forName("com.atguigu.review.Animal");

Object obj = clazz.newInstance();

Animal a = (Animal)obj;

//调用非public的属性

Field f1 = clazz.getDeclaredField("name");

f1.setAccessible(true);

f1.set(a, "Jerry");

//调用public的属性

Field f2 = clazz.getField("age");

f2.set(a, 9);

System.out.println(f2.get(a));

System.out.println(a);

//调用static的属性

Field f3 = clazz.getDeclaredField("desc");

System.out.println(f3.get(null));

}

//调用指定的方法

@Test

public void test4() throws Exception{

Class clazz = Class.forName("com.atguigu.review.Animal");

Object obj = clazz.newInstance();

Animal a = (Animal)obj;

//调用非public的方法

Method m1 = clazz.getDeclaredMethod("getAge");

m1.setAccessible(true);

int age = (Integer)m1.invoke(a);

System.out.println(age);

//调用public的方法

Method m2 = clazz.getMethod("show", String.class);

Object returnVal = m2.invoke(a,"金毛");

System.out.println(returnVal);

//调用static的方法

Method m3 = clazz.getDeclaredMethod("info");

m3.setAccessible(true);

// m3.invoke(Animal.class);

m3.invoke(null);

}

下面是具体的一个demo。通过反射机制来调用person类的方法属性等

person类如下

package 反射机制;

public class Person {
public String name ;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Person(String name, Integer age) {
super();
this.name = name;
this.age = age;
}
public Person() {
super();
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public void show() {
System.out.println("我是一个人");
}
public void display(String nation)
{
System.out.println("我的国籍是"+nation);
}

}

测试类如下:

package 反射机制;

import java.lang.annotation.Annotation;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.lang.reflect.ParameterizedType;

public class TestPerson {
//有了反射通过反射创建一个类的对象,并调用其中的结构
public static void main(String[] args) throws Exception {
Class clazz=Person.class;
//创建clazz对应的运行时类Person类的对象
Person p=(Person)clazz.newInstance();
System.out.println(p);
//通过反射调用属性
Field f1=clazz.getField("name");
f1.set(p, "刘德华");
System.out.println(p);

Field f2=clazz.getDeclaredField("age");//可以使声明的无论是否为私有的都可以调用
f2.setAccessible(true);
f2.set(p, 20);
//如果没有f2.setAccessible(true)则System.out.println(p);报java.lang.NoSuchFieldException异常,只有public可以直接调
System.out.println(p);
//通过反射调用方法
Method m1=clazz.getMethod("show");//getmethods获取的是方法数组
m1.invoke(p);
Method m2=clazz.getMethod("display",String.class);

m2.invoke(p, "CHN");
Method[] m3=clazz.getMethods();//获取运行时类本身及其父类声明的所有的public方法
for(Method m : m3) {
System.out.println(m);
}
System.out.println("..................");
Method[] m4=clazz.getDeclaredMethods();//获取运行时类本身声明的所有的方法
for(Method m : m4) {
System.out.println(m);
}
//获取注解
for(Method ann : m4) {
Annotation []ann1 =ann.getAnnotations();
for(Annotation a:ann1) {
System.out.println(a);
}

//获取类的权限修饰符
String str=Modifier.toString(ann.getModifiers());
System.out.println(str);
//获取类方法的返回值
Class returnType =ann.getReturnType();
System.out.println(returnType);
//方法名
System.out.println(ann.getName()+" ");
//形参列表
System.out.print("(");
Class []params= ann.getParameterTypes();
for (int i = 0; i < params.length; i++) {
System.out.print(params[i].getName()+"args-"+i+" ");
}
System.out.println(")");
//异常处理
Class []exps=ann.getExceptionTypes();
if(exps.length!=0) {
System.out.println("throws");
}
for (int j = 0; j < exps.length; j++) {
System.out.println("throws"+exps[j].getName());
}
//获取父类
Class superClass =clazz.getSuperclass();
System.out.println(superClass);
//获取带泛型的父类
java.lang.reflect.Type type1=clazz.getGenericSuperclass();
System.out.println(type1);
//获取父类的泛型
ParameterizedType param=( ParameterizedType)type1;
java.lang.reflect.Type[]ars=param.getActualTypeArguments();
System.out.println((Class)ars[0]);//获取带个参数
//获取实现的接口
Class[] intrfaces =clazz.getInterfaces();
for(Class i : intrfaces)
{
System.out.println(i);

}

}

}
}

下面的demo则表明了一个类的Class对象的唯一性的特点

package 反射;
/**
* 测试各种类型(class,interface,enum,annotation,primitive type,void)java.lang.Class对象的获取方式
*
* @author 19575
*
*/
@SuppressWarnings("all")
public class Demo01 {
public static void main(String[] args) throws Exception {
String path="反射.User";
//对象是表示或封装一些数据,一个类被加载后,JVM会创建一个对应类的Class对象,类的整个结构信息会放到对应类的Class对象中
//这个Class对象就像一面镜子,通过这面镜子我们可以看到类的全部信息
Class clazz01=Class.forName(path);
Class clazz02=path.getClass();//都是获取Class的方法
System.out.println(clazz01.getName());
System.out.println(clazz02.getName());
System.out.println(clazz01.hashCode());
System.out.println(clazz02.hashCode());//发现name和hashcode值都完全相同则表明一个类只有一个Class对象
//对于数组长度可以不一致,但是维度必须一致,类型一致,Class才会相同
int []arr01=new int[10];
int [][]arr02=new int[30][3];
int []arr03=new int[30];
double []arr04=new double[10];
System.out.println(arr01.getClass().hashCode());//118352462
System.out.println(arr02.getClass().hashCode());//1550089733
System.out.println(arr03.getClass().hashCode());//118352462
System.out.println(arr04.getClass().hashCode());//865113938

}
}

总结:总的来说反射机制可以获取对应的运行时类的完整的类的结构:属性、方法、构造器、包、父类、接口、泛型、注解、异常、内部类。。。

java反射机制基础总结的更多相关文章

  1. java反射机制(基础版)

    package com.reflect; import java.lang.reflect.Constructor; import java.lang.reflect.Field; import ja ...

  2. java反射机制基础

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

  3. JAVA反射机制基础概念

    反射机制:所谓的反射机制就是java语言在运行时拥有一项自观的能力.通过这种能力可以彻底的了解自身的情况为下一步的动作做准备.下面具体介绍一下java的反射机制.这里你将颠覆原来对java的理解. J ...

  4. java基础知识(十一)java反射机制(上)

    java.lang.Class类详解 java Class类详解 一.class类 Class类是java语言定义的特定类的实现,在java中每个类都有一个相应的Class对象,以便java程序运行时 ...

  5. 【java基础】Java反射机制

    一.预先需要掌握的知识(java虚拟机)  1)java虚拟机的方法区:  java虚拟机有一个运行时数据区,这个数据区又被分为方法区,堆区和栈区,我们这里需要了解的主要是方法区.方法区的主要作用是存 ...

  6. Java基础学习总结(75)——Java反射机制及应用场景

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

  7. 夯实Java基础(二十一)——Java反射机制

    1.反射机制概述 Java反射机制是指程序在运行状态中,对于任何一个类,我们都能够知道这个类的所有属性和方法(包括private.protected等).对于任何一个对象,我们都能够对它的属性和方法进 ...

  8. Java 基础之详解 Java 反射机制

    一.什么是 Java 的反射机制?   反射(Reflection)是Java的高级特性之一,是框架实现的基础,定义:JAVA反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法: ...

  9. java基础知识(十一)java反射机制(下)

    1.什么是反射机制? java反射机制是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法,对于任意一个对象都能够调用他的属性和方法,这种动态获取属性和方法的功能称为java的反射机制. ...

随机推荐

  1. 怎样做大做强企业中的ERP?

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/luozhonghua2014/article/details/37672409           ...

  2. swift开发学习笔记-闭包

    版权声明:本文为博主原创文章,未经博主同意不得转载. https://blog.csdn.net/jiangqq781931404/article/details/32913421 文章转自:http ...

  3. SAP数据表相关

    [转]SAP 数据表相关信息 今天用到了根据字段取数据元素描述,以前做过忘啦,在谢兄的帮助下搞定,把他的总结粘出来记住. 存储域(Domain)信息的表为DD01L:存储数据元素(Data Eleme ...

  4. Vue:实践学习笔记(6)——使用SLOT分发内容

    Vue:实践学习笔记(6)——使用SLOT分发内容 Slot Slot是什么 Slot是父子组件的通讯方式,可以将父组件的内容显示到子组件之中. 使用SLOT前 比如我在定义组件的时候,在里面输入了X ...

  5. maven采用tomcat7启动项目

    1.maven 集成tomcat7启动项目 <plugin> <groupId>org.apache.tomcat.maven</groupId> <arti ...

  6. L97

    We are young. So let's set the world on fire. We can burn brighter than the sun.我们是青年,让我们点亮世界,释放生命,胜 ...

  7. 开机时遇到grub rescue无法进入系统的解决方法

    装双系统(win10和elementary os),elementary os是ubuntu的一个分支.在win10中合并了一块空白磁盘分区,再开机的时候出问题了. 遇到filesystem unkn ...

  8. selenium 经常用到的API

    一.webdriver 属性及方法: 1.获取当前页面的 url driver.current_url 2 .获取窗口相关信息 get_window_position() 返回窗口x,y坐标 get_ ...

  9. 机器学习: R-CNN, Fast R-CNN and Faster R-CNN

    做语义分割的大概都知道这几篇文章了,将一个传统的计算机视觉模型,用CNN一点一点的替换,直到最后构建了一个完整的基于CNN的端到端的模型.这几篇文章有一定的连贯性.从中可以看到一种研究的趋势走向. 上 ...

  10. BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组

    BZOJ_1818_[Cqoi2010]内部白点 _扫描线+树状数组 Description 无限大正方形网格里有n个黑色的顶点,所有其他顶点都是白色的(网格的顶点即坐标为整数的点,又称整点).每秒钟 ...