1、首先一个问题,什么是类,类是不是对象?

我们总是说我们new一个对象出来

那么我们还没有new的时候,建造的那个java类是不是对象呢?

它是java.lang.Class的对象

对于反射我们首先要知道的就是什么是Class类

java.lang.Class到底是什么,有啥用。

首先我们要得到Class,我们有三种可以得到的方法,代码如下,c1,c2,c3就是我们需要的Class

//任何一个类都有一个隐含的成员变量叫做calss
Class c1 = Man.class; //通过对象的getClass方法获取class
Class c2 = man1.getClass(); //c1和c2表示了Man的类类型,也就是class type Class c3 = null;
c3 = Class.forName("com.clazz.test.Man");

需要知道的是类的类类型是一样的,都指的是一个,所以c1,c2,c3都是一样的。都是相等的。

那我们现在已经拿到了Class,可以用它来干嘛呢?

我们可以通过类的类类型直接创建一个对象,也就是说,没有new了。

需要注意的是下面的代码中newInstance方法会调用类的无参构造方法

//通过类的类类型创建对象。
Man man2 = (Man) c1.newInstance();

下面是所有的测试代码

package com.clazz.test;

/**
* Class类的描述测试
* @author XX
*
*/
public class ClazzDemo1 { public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
//Man是java.lang.Class的对象
//任何一个类都是class类的实例对象 Man man1 = new Man();
//man1是Man类的实例对象 //任何一个类都有一个隐含的成员变量叫做calss
Class c1 = Man.class; //通过对象的getClass方法获取class
Class c2 = man1.getClass(); //c1和c2表示了Man的类类型,也就是class type Class c3 = null;
c3 = Class.forName("com.clazz.test.Man"); //通过类的类类型创建对象。
Man man2 = (Man) c1.newInstance();
}
} class Man{
public Man(){
System.out.println("创建了这个类");
}
}

2、静态加载类和动态加载类

new创建对象是静态加载,在编译时刻就需要加载所有可能使用到的类。

通过动态加载类,可以在运行时刻加载使用到的类

也就是我们的c3使用的方法

package com.clazz.test;

public class DynamicLoadClass {

    public static void main(String args[]) throws ClassNotFoundException, InstantiationException, IllegalAccessException
{
//静态加载类,直接new出对象,调用方法,一般都是使用这个,但是一旦没有Student类,编译就会报错
//而且如果需要使用老师对象那么代码需要重新写过很多,要把new对象重新写过,
Student s1 = new Student();
s1.speck(); //通过动态加载类,编译时刻,无论学生还是老师类存不存在,都可以编译通过,只有当运行时刻才进行加载
//好处是如果你需要新增一个类,直接实现IPeople接口,只要forName的名字正确即可,而且这个名字可以
//作为一个参数传进来然后进行修改
Class c1 = Class.forName("com.clazz.test.Student");
IPeople p1 = (IPeople) c1.newInstance();
p1.speck();
}
}
package com.clazz.test;

public class Student implements IPeople{

    public void speck()
{
System.out.println("我是学生");
}
}
package com.clazz.test;

public interface IPeople {

    public void speck();
}

3通过反射拿到一个类的所有的信息

下面这个就是反射最基本的用法,也是反射最神奇的地方

package com.clazz.util;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method; import com.clazz.test.Student; /**
* calss类的测试工具类
* @author XX
*
*/
public class ClazzUtil { public static void main(String args[])
{
//通过反射能拿到类的所有方法信息
printAll(new Student());
} /**
* 获取这个对象的信息并打印出来
*/
public static void printAll(Object object)
{
Class c = object.getClass(); //打印该类的名字
System.out.println("类的名字" + c.getName()); //打印该类的所有方法(包含从父类继承来的)(不包含私有的方法)
Method[] ms = c.getMethods();
for (Method method : ms) {
System.out.println("方法:" + method.getName() + " 方法的返回值:" + method.getReturnType().getName()); //获取方法的参数
Class<?>[] par = method.getParameterTypes();
for (Class<?> class1 : par) {
System.out.println("方法的入参:" + class1.getName());
}
} //打印该类的方法(不包含从父类继承来的)包含私有方法
Method[] ms2 = c.getDeclaredMethods();
for (Method method : ms2) {
System.out.println("方法1:" + method.getName() + " 方法的返回值:" + method.getReturnType().getName());
} //获取成员变量(不包含私有变量)
Field[] fs = c.getFields();
for (Field field : fs) {
System.out.println("成员变量: " + field.getName());
} //获取成员变量(包含私有变量)
Field[] fs1 = c.getDeclaredFields();
for (Field field : fs1) {
System.out.println("成员变量: " + field.getName());
} //获取构造方法
Constructor[] con = c.getDeclaredConstructors();
for (Constructor constructor : con) {
System.out.println("构造方法:" + constructor.getName());
}
}
}
package com.clazz.test;

public class Student implements IPeople{

    private int a1;
public int a12; public void speck()
{
System.out.println("我是学生");
} private void speck2()
{
System.out.println("我是学生");
}
}

4通过反射调用类的方法

这个是反射的应用,通过反射调用一个类的方法

package com.clazz.test;

import java.lang.reflect.Method;

/**
* @author XX
*
*/
public class ReflectMethod { public static void main(String args[]) throws Exception
{
A a = new A(); Class c = a.getClass(); Method m = c.getMethod("add", int.class,int.class); System.out.println(m.invoke(a, 1,2));
}
} class A{
public int add(int a,int b)
{
return a+b;
}
private int minus(int a,int b)
{
return a-b;
}
}

5利用反射解释ArrayList的泛型

package com.clazz.test;

import java.lang.reflect.Method;
import java.util.ArrayList; public class ArrayListRflect { public static void main(String args[]) throws Exception
{
/**
* 下面的代码用于证明,在ArrayList中,泛型只在编译之前有效,编译之后泛型对于list的限制
* 是无效的。利用反射就能绕过编译这个阶段在ArrayList添加本不属于该泛型的值
*/
ArrayList<String> list = new ArrayList<String>(); list.add("哈哈");
//list.add(1);如果原来这么写,编译会报错的 //那么怎么在list放个int的1呢? //获取list的类类型
Class c = list.getClass();
//通过类类型拿到方法
Method m = c.getMethod("add",Object.class);
//通过反射调用方法
m.invoke(list, 1); System.out.println(list);
//结果为:[哈哈, 1] //所以证明了上面的观点,也同时很好的证明了反射多神奇
}
}

java反射简解的更多相关文章

  1. Java 反射详解 转载

    java 反射 定义 功能 示例 概要: Java反射机制详解 | |目录 1反射机制是什么 2反射机制能做什么 3反射机制的相关API ·通过一个对象获得完整的包名和类名 ·实例化Class类对象 ...

  2. java反射 详解!!!!

    java反射(特别通俗易懂) 反射是框架设计的灵魂 (使用的前提条件:必须先得到代表的字节码的Class,Class类用于表示.class文件(字节码)) 一.反射的概述 JAVA反射机制是在运行状态 ...

  3. java反射详解及说明

    首先写一个Person类: package lltse.base.reflectdemo; public class Person { private String name ="张三&qu ...

  4. 【转载】Java 反射详解

    目录 1.什么是反射? 2.反射能做什么? 3.反射的具体实现 4.根据反射获取父类属性 4.反射总结 反射反射,程序员的快乐! 1.什么是反射? Java反射就是在运行状态中,对于任意一个类,都能够 ...

  5. 《Java基础知识》Java 反射详解

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

  6. java 反射详解

    反射的概念和原理 类字节码文件是在硬盘上存储的,是一个个的.class文件.我们在new一个对象时,JVM会先把字节码文件的信息读出来放到内存中,第二次用时,就不用在加载了,而是直接使用之前缓存的这个 ...

  7. java反射详解

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  8. java反射详解(转)

    本篇文章依旧采用小例子来说明,因为我始终觉的,案例驱动是最好的,要不然只看理论的话,看了也不懂,不过建议大家在看完文章之后,在回过头去看看理论,会有更好的理解. 下面开始正文. [案例1]通过一个对象 ...

  9. Java反射详解及应用示例

    反射是Java中最重要的内容之一,了解反射原理对我们学习各种框架具有很大的帮助 反射的原理: 反射应用示例: import java.lang.reflect.Constructor; import ...

随机推荐

  1. 基于Flash与window平台本地程序通信实现媒体流发布

    0 Web场景下的媒体流发布可以采用Flash原生API实现,但是Flash H264视频压缩参数不可控.音频无法AAC编码,所以一般采用浏览器插件方式,但是浏览器插件有版本兼容问题.不稳定,所以可以 ...

  2. KVM 虚拟机基本管理及常用命令

    KVM的基本管理 1.查看KVM虚拟机配置文件 #Kvm虚拟机默认配置文件位置 [root@kvm qemu]# pwd /etc/libvirt/qemu [root@kvm qemu]# ll t ...

  3. js 鸭式辨型法

    无意中看到arr.length === +arr.length;这句代码,然后就去了解了下 这是一种鸭式辨型的判断方法. 鸭式辨型:像鸭子一样走路.游泳和嘎嘎叫的鸟就是鸭子 这句话表示: a.arr有 ...

  4. 2. Shell 传递参数

    1. 概要 我们可以在执行 Shell脚本时,向脚本传递参数,脚本内获取参数的格式为:$n.n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数,以此类推-- #!/bin/bas ...

  5. Power oj2498/DP/递推

    power oj 2498 /递推 2498: 新年礼物 Time Limit: 1000 MS Memory Limit: 65536 KBTotal Submit: 12 Accepted: 3  ...

  6. NOIP2015普及组第四题推销员

    好久没有写博客了,今天再写一篇.还是先看题: 试题描述 阿明是一名推销员,他奉命到螺丝街推销他们公司的产品.螺丝街是一条死胡同,出口与入口是同一个,街道的一侧是围墙,另一侧是住户.螺丝街一共有 N 家 ...

  7. ACM心路

    又到了夏天了,这个季节最容易发春,最近上课效率怎么这么低,哎,,别发春了,好好学习,天天向上,现在想妹子,都是空想,没有什么实际意义,纯属浪费时间,浪费生命,不如节约点时间到学习上,不学无术,到嘴边的 ...

  8. android应用的优化建议(转载)

    首先,这是我在http://www.oschina.net/translate/40-developer-tips-for-android-optimization看到的一片文章,感觉挺有道理的,所以 ...

  9. ZUFE OJ 2289 God Wang II

    Description 这个世界太无聊了,于是God Wang想出了新的运算符号$,对于两个数x,y来说x$y的值等于x和y各个位置上的数字乘积之和,没有的位按0来算 比如说123$321=1*3+2 ...

  10. 如何在sharepoint里通过correlation id查找详细的错误信息

    Sharepoint里我们经常遇到这样的错误信息: 我们能通过下面的power shell 命令来查到详细的错误信息: $correlationid = "943e6e9c-b5d9-207 ...