`
maximilian_kevin
  • 浏览: 1692 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
最近访客 更多访客>>
社区版块
存档分类
最新评论

java反射学习笔记

阅读更多
    浑浑噩噩毕业半年多,对于以前学的逻辑的知识也忘记的差不多了,看来是没有希望回去做逻辑了.只能继续自己的码农之路.啥都不懂,但是还是写点东西权当自己的笔记吧.
    最近自己在看spring框架,虽然对于spring的了解完全是菜鸟级,但是还是看到了点java的反射的应用.之前对于反射一知半解,决定自己写几个test学习下.
    关于原理什么的完全不知道,以后有时间在去深究吧,毕竟对于我这种菜鸟来说先学点来用就可以混下了.那么高深的要积累才能看的吧.
    对于一个正在运行的程序,如果能够了解到他其中的类属性以及域属性那是多好美妙的事情.java的反射就是实现这个.
这里主要有3个类:

TaskStarter定时执行任务
package com.maximilian.www;

import java.util.Timer;

public class TaskStarter 
{
	private static final long delayTime=1000;
	private static final long intervalTime=2000;
	private static Timer timer = new Timer();
	public static void main(String [] args)
	{
		System.out.println("start task!");
		timer.schedule(new IntervalTask(), delayTime, intervalTime);
	}
}


IntervalTask:任务
package com.maximilian.www;

import java.util.TimerTask;
import test.ReflectionTest;

public class IntervalTask extends TimerTask
{
	public int tmpInt=0;
	public String tmpString="0";
	
	private String string1 = "1";
	private static String string2 = "2";
	public String string3 = "3";
	public static String string4 = "4";
	public IntervalTask(int argInt,String argString)
	{
		this.tmpInt=argInt;
		this.tmpString=argString;
	}
	
	@Override
    public void run()
    {
	    System.out.println("----------------"); 
	    ReflectionTest test = new ReflectionTest();
	    System.out.println(test.getObjectProperty(this, "string3"));
	    Object[] args ={1,"1"};
	    test.getAndInvokeMethod(this, null, "print1");
	    test.getAndInvokeMethod(this, args, "print5");
	    
    }
	private void print1()
	{
		System.out.println("string1:"+string1+"\r\n"+"string2:"+string2+"\r\n"+"string3:"+string3+"\r\n"+"string4:"+string4+"\r\n");
	}
	private static void print2()
	{
		System.out.println("string2:"+string2+"\r\n"+"string4:"+string4+"\r\n");
	}
	public void print3()
	{
		System.out.println("string1:"+string1+"\r\n"+"string2:"+string2+"\r\n"+"string3:"+string3+"\r\n"+"string4:"+string4+"\r\n");
	}
	public static void print4()
	{
		System.out.println("string2:"+string2+"\r\n"+"string4:"+string4+"\r\n");
	}
	public static void print5(int argInt, String argString)
	{
		System.out.println("string2:"+string2+"\r\n"+"string4:"+string4+"\r\n");
	}
	public  void print6(int argInt, String argString)
	{
		System.out.println("string2:"+string2+"\r\n"+"string4:"+string4+"\r\n");
	}
}


ReflectionTest:测试反射

主要可以做到的就是下面:

1. 新建某个类的实例

	    Class<?> taskClass = Class.forName("com.maximilian.www.IntervalTask");
	    Constructor<?> con = taskClass.getConstructor(new Class[]{});
	    Object obj1 = con.newInstance();
	    System.out.println(obj1.toString());
	    System.out.println("tmpInt:"+((IntervalTask)obj1).tmpInt+"  tmpString:"+((IntervalTask)obj1).tmpString);


打印结果: com.maximilian.www.IntervalTask@12940b3
tmpInt:0  tmpString:0
上面是类的不带参的构造函数,当然也可以调用带参数的不同的构造函数.
如果: IntervalTask的构造函数有public IntervalTask(int argInt,String argString),那么可以通过下面新建实例:

	    Class<?> [] parameterTypes = {int.class,String.class};
	    Constructor<?> con2 = taskClass.getConstructor(parameterTypes);
	    Object [] paramters ={1,"1"};
	    Object obj2 = con2.newInstance(paramters);
	    System.out.println(obj2.toString());
	    System.out.println("tmpInt:"+((IntervalTask)obj2).tmpInt+"  tmpString:"+((IntervalTask)obj2).tmpString);


打印结果: com.maximilian.www.IntervalTask@158f9d3
tmpInt:1  tmpString:1

2. 获取某个类的静态属性

	    Field field =taskClass.getField("string4");
Object value = field.get(taskClass);
	    System.out.println(value);


这里的有另外一个方法getDeclaredField与getField区别就是前面可以获取类的私有属性.
当不清楚属性的名称时可以获取一次获取全部的
    Field [] field =taskClass. getDeclaredFields();
对于类中域不知道类型可以通过:
    Field field =taskClass.getField("string4");
    Class<?> typeClass = field.getType();
    做修改的话如下(这里的修改对于运行的程序没有作用,可以通过传入运行程序的类对象在这里做修改):

field.setAccessible(true);
Constructor<?> constructor = typeClass.getConstructor(String.class);
	    Object object = constructor.newInstance("11");
	    field.set(taskClass,object);
	    Object value = field.get(taskClass);
	    System.out.println(value);
	    field.setAccessible(false);


3. 获取某个类的静态方法执行

对于private方法:

	    Method method = taskClass.getDeclaredMethod("print2");
	    method.setAccessible(true);
	    method.invoke(taskClass, null);
	    method.setAccessible(false);


对于public方法:

	    Method method = taskClass.getMethod("print4");
	    method.invoke(taskClass, null);


对于带参数的方法调用

	    Class[] argclass = {int.class,String.class};
	    Object [] arg={1,"1"};
	    Method method3 = taskClass.getMethod("print5",argclass);
	    method2.invoke(taskClass, arg);

   
4. 获取某个对象的属性

	public Object getAndChangeObjectProperty(Object obj,String fieldName)
	{
		Class<?> taskClass = obj.getClass();
		Object value = null;
		try
        {
	        Field field =taskClass.getDeclaredField(fieldName);
	        field.setAccessible(true);
	        field.set(obj, "new");
	        value = field.get(obj);
	        field.setAccessible(false);
        } catch (NoSuchFieldException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (SecurityException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (IllegalArgumentException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (IllegalAccessException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
		return value;
	}


5. 获取某个对象的方法执行

	public void getAndInvokeMethod(Object obj,Object [] args,String methodName)
	{
		Class<?> taskClass = obj.getClass();
		Method method= null;
		try
        {
			if(args==null)
			{
				method = taskClass.getDeclaredMethod(methodName);				
			}
			else
			{
			    Class[] argclass = {int.class,String.class};
			    method = taskClass.getDeclaredMethod(methodName, argclass);
			}
	        method.setAccessible(true);
	        method.invoke(obj, args);
	        method.setAccessible(false);
        } catch (NoSuchMethodException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (SecurityException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (IllegalAccessException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (IllegalArgumentException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        } catch (InvocationTargetException e)
        {
	        // TODO Auto-generated catch block
	        e.printStackTrace();
        }
	}


test.getAndInvokeMethod(this, null, "print1")和test.getAndInvokeMethod(this, args, "print5")有参和无参时调用方法。
    Java的反射最大的特别是在运行时来做上面的操作。上面的都是一些基本用法,反射提供很多其他好用的方法,如判断某一个对象是否是类的对象的isinstance;一些获取基类的属性和方法(通过继承类的class.getSuperclass()后得到基类的class,后面的操作类似)等。
    个人对于object.getclass与Class.Forname(package.classname)区别的理解:
前者是得到内存中的类对象,而后者得到的是内存中的类文件,但是最终得到的都是内存中同一块一样的东西,因为对于个类文件来讲只会在java虚拟机中加载一个类对象。前面的例子中,对于不是静态属性或者方法的是否可调用决定在于具体的对象是否在堆中建立。

分享到:
评论

相关推荐

    Java基础 学习笔记 Markdownr版

    本学习笔记主要涵盖了Java的基础知识,包括面向对象、集合、IO流、多线程、反射与动态代理以及Java 8的新特性等方面,旨在帮助初学者或有经验的开发者巩固和提升Java编程技能。 1. 面向对象(OOP):Java的核心是...

    java注解和反射的个人学习笔记

    java注解和反射的个人学习笔记

    Java反射学习笔记

    Java反射是Java编程语言中的一个强大特性,允许程序在运行时动态地获取类的信息并操作类的对象。在Java中,反射主要用于以下场景:动态加载类、访问私有成员、调用私有方法以及处理泛型等。以下是关于Java反射的一些...

    java学习笔记markdown

    8. **反射机制**:探讨Java反射API的使用,包括动态获取类信息、创建对象、调用方法等功能,这对于理解和调试程序有很大的帮助。 9. **JVM内部机制**:简述Java虚拟机的工作原理,包括类加载、内存管理、垃圾回收...

    Java入门学习笔记

    "Java入门第三季学习笔记"可能涵盖了更多高级话题,如反射、注解、设计模式和Java库的使用。反射允许程序在运行时检查类、接口、字段和方法的信息,提供了更大的灵活性。注解是一种元数据,可以用来提供编译器或运行...

    java学习笔记java反射机制

    java学习笔记java反射机制

    java学习——java中的反射学习笔记.rar_java 反射

    本篇笔记将深入探讨Java反射的概念、重要性以及如何使用。 一、反射基础 1. 类加载:当Java虚拟机(JVM)加载一个类时,它会创建该类的Class对象。这个对象包含了关于类的所有信息,包括方法、字段、构造器等。...

    java学习笔记(java 反射机制 流 内存管理)

    本笔记主要涵盖了四个核心知识点:Java反射机制、流(I/O流)、内存管理和Java学习的基础。以下是对这些主题的详细阐述: 一、Java反射机制 Java反射机制是Java语言的一个强大特性,允许程序在运行时检查类、接口、...

    JAVA学习笔记 林信良

    《JAVA学习笔记》是林信良先生的一部深入浅出的Java编程教程,旨在帮助初学者和有一定经验的开发者巩固和提升Java编程技能。这本书涵盖了Java语言的基础到高级概念,是一份宝贵的自学资料。 首先,从基础部分开始,...

    java反射笔记

    在“java反射笔记”这个主题中,我们将深入探讨反射的基础知识和常见用法。 首先,我们需要了解什么是反射。在Java中,反射是指在运行时获取类的信息(如类名、方法名、参数类型等)并动态调用对象的方法或访问其...

    Java学习笔记(源码)

    8. **反射机制**:Java反射API允许在运行时动态访问类的信息,包括类名、方法、字段等。学习笔记会讲解如何使用反射进行元编程,以及其在插件系统、序列化和动态代理中的应用。 9. **Java API和库**:Java标准库...

    java反射机制学习笔记

    Java反射机制是Java编程语言的一项重要特性,它允许程序在运行时动态地获取类的信息,并且能够对类的属性和方法进行操作。反射机制的核心在于Java的`java.lang.reflect`包,其中包含了`Class`、`Constructor`、`...

    Java基础尚硅谷宋红康学习笔记

    1. **反射**:Java反射机制允许在运行时检查类的信息(如类名、方法、字段等),并能动态调用方法和修改字段值,增强了代码的灵活性。 2. **泛型**:泛型提供了一种在编译时检查类型安全的方法,允许在类、接口和...

    java校招学习笔记

    "java校招学习笔记"显然是针对应届毕业生或求职者准备的,旨在帮助他们掌握Java的基础知识和校招面试中常见的技术问题。这份笔记可能包含了从基础概念到进阶主题的全面概述,以提高求职者的竞争力。 首先,Java的...

    java超强学习笔记

    "Java超强学习笔记"显然是一份全面且深入的Java学习资料,由一位极具洞察力和组织能力的作者精心编纂。这份笔记可能包含了从基础知识到高级特性的全方位讲解,旨在帮助学习者构建坚实的Java编程基础,并提升他们的...

    Java学习笔记(必看经典).doc

    这份“Java学习笔记(必看经典).doc”文档将涵盖Java的核心概念和重要知识点,对于初学者和有经验的开发者来说都是宝贵的参考资料。 首先,Java的基础部分通常包括以下几个方面: 1. **Java语法基础**:这是所有...

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip

    基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码.zip 基于java的开发源码-java多线程反射泛型及正则表达式学习笔记和源码....

Global site tag (gtag.js) - Google Analytics