1. java反射机制怎样调用类的私有方法
的一段简易实例代码如下:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
* @author thomaslwq
* @version 创建时间:Sep 4, 2012 9:53:49 PM
* 类说明
*/
public class ReflectionTest {
public static void setObjectColor(Object obj) throws SecurityException, NoSuchMethodException, IllegalArgumentException, IllegalAcces***ception, InvocationTargetException{
Class cls = obj.getClass();
//获得类的私有方法
Method method = cls.getDeclaredMethod("privateMethod", null);
method.setAccessible(true); //没有设置就会报错
//调用该方法
method.invoke(obj, null);
}
public static void main(String args[]) throws SecurityException, IllegalArgumentException, NoSuchMethodException, IllegalAcces***ception, InvocationTargetException{
setObjectColor(new MyTest());
}
}
//测试类
class MyTest{
public void setMyTest(){
System.out.println("setMyTest");
}
/**
类的私有方法
**/
private void privateMethod(){
System.out.println("调用了 private Method");
}
}
2. java反射方法调用问题
int是基本类型没错,因此,在用反射调用时,应明确使用Integer才行。
由于参数是从数据库内里来容的(ResultSet),因此,要看数据库的定义,以及数据库的类型。
比如,对于Oracle 定义的任何数值类型字段,都会返回Decimal对象,由于float类型能运行,推断应该不使用的ORACLE,还是看你的数据库定义吧,实在不行,就要做下面的工作,增加一个TypeConvertor定义,其中实现将数据库返回的对象转换成方法参数所需的类型,针对几种基本数据类型进行简单的转换,就不需要依赖数据库了。
1楼的是想自己做持久类框架??
3. JAVA中反射是什么
JAVA中反射是动态获取信息以及动态调用对象方法的一种反射机制。
Java反射就是在运行状态中,对于任意一个类,都能够知道这个类的所有属性和方法;对于任意一个对象,都能够调用它的任意方法和属性;并且能改变它的属性。而这也是Java被视为动态语言的一个关键性质。
Java反射的功能是在运行时判断任意一个对象所属的类,在运行时构造任意一个类的对象,在运行时判断任意一个类所具有的成员变量和方法,在运行时调用任意一个对象的方法,生成动态代理。
(3)java反射调用函数扩展阅读:
JAVA中反射实例:
1、Class superClass=clazz.getSuperclass();//获取父类。
System.out.println("getSuperclass:"+superClass)。
2、Class[] interfaces=clazz.getInterfaces();//获取实现接口。
System.out.println("getInterfaces:"+interfaces.length)。
3、Constructor[] cons=clazz.getConstructors();//构造方法。
System.out.println("getConstructors:"+cons.length)。
参考资料来源:网络: JAVA反射机制
4. java中反射的三种方法是
java中反射的三种方法:
1. 通过Object类的getClass方法来获取
java.lang.Object中定义有getClass方法:public final Class getClass()
所有Java对象都具备这个方法,该方法用于返回调用该方法的对象的所属类关联的Class对象,例如:
Date date1 = new Date();
Date date2 = new Date();
Class c1 = date1.getClass();
Class c2 = date2.getClass();
System.out.println(c1.getName());
// java.util.Date
System.out.println(c1 == c2);
// true
上面的代码中,调用Date对象date1的getClass方法将返回用于封装Date类信息的Class对象。
这里调用了Class类的getName方法:public String getName(),这个方法的含义很直观,即返回所封装的类的名称。
需要注意的是,代码中的date1和date2的getClass方法返回了相同的Class对象(c1==c2的值为true)。这是因为,对于相同的类,JVM只会载入一次,而与该类对应的Class对象也只会存在一个,无论该类实例化了多少对象。
另外,需要强调的是,当一个对象被其父类的引用或其实现的接口类型的引用所指向时,getClass方法返回的是与对象实际所属类关联的Class对象。例如:
List list = new ArrayList();
System.out.println(list.getClass().getName()); // java.util.ArrayList
上面的代码中,语句list.getClass()方法返回的是list所指向对象实际所属类java.util.ArrayList对应的 Class对象而并未java.util.List所对应的Class对象。有些时候可以通过这个方法了解一个对象的运行时类型,例如:
HashSet set = new HashSet();
Iterator it = set.iterator();
System.out.println(it.getClass().getName()); //java.util.HashMap$KeyIterator
从代码可以看出,HashSet的iterator方法返回的是实现了Iterator接口的HashMap内部类(KeyIterator)对象。
因为抽象类和接口不可能实例化对象,因此不能通过Object的getClass方法获得与抽象类和接口关联的Class对象。
2. 使用.class的方式
使用类名加“.class”的方式即会返回与该类对应的Class对象。例如:
Class clazz = String.class;
System.out.println(clazz.getName()); // java.lang.String
这个方法可以直接获得与指定类关联的Class对象,而并不需要有该类的对象存在。
3. 使用Class.forName方法
Class有一个著名的static方法forName:public static Class forName(String className) throws ClassNotFoundException
该方法可以根据字符串参数所指定的类名获取与该类关联的Class对象。如果该类还没有被装入,该方法会将该类装入JVM。
该方法声明抛出ClassNotFoundException异常。顾名思义,当该方法无法获取需要装入的类时(例如,在当前类路径中不存在这个类),就会抛出这个异常。
例如,如果当前类路径中存在Foo类:
package org.whatisjava.reflect;
public class Foo {
public Foo() {
System.out.println("Foo()");
}
static {
System.out.println("Foo is initialized");
}
}
运行下面的代码:
Class clazz = Class.forName("org.whatisjava.reflect.Foo");
控制台会有如下输出:
Foo is initialized
Class.forName("org.whatisjava.reflect.Foo")首先会将reflection.Foo类装入JVM,并返回与之关联的Class对象。JVM装入Foo类后对其进行初始化,调用了其static块中的代码。需要注意的是:forName方法的参数是类的完 整限定名(即包含包名)。
区别于前面两种获取Class对象的方法:使用Class.forName方法所要获取的与之对应的Class对象的类可以通过字符串的方式给定。该方法通常用于在程序运行时根据类名动态的载入该类并获得与之对应的Class对象。
通过上面的文章相信你对java的反射机制有了一定的认识,同时也对java中Class类的用法有了比较清晰的理解,在我们实际工作的过程中,我们不断的运用java知识来解决实际生活中的问题的时候我们就能对java反射机制有一个更深入的理解!
二、代码示例
1.ClassTest.java
[java] view plain
/**
* java中Class类的使用
*/
import java.io.*;
import java.lang.reflect.*;
public class ClassTest1 {
public ClassTest1(){
}
public static void main(String[] args) throws Exception{
ClassTest1 test=new ClassTest1();
ClassTest1 test1=test.getClass().newInstance();
//test1=test;
test.printMessage();
test1.printMessage();
System.out.println(test.hashCode());
System.out.println(test1.hashCode());
Method[] method=test1.getClass().getMethods();
for(Method m :method){
System.out.println(m.getDeclaringClass());
System.out.println(m.getName());
}
}
public void printMessage(){
System.out.println("Created successful!");
}
}
运行结果:
[plain] view plain
Created successful!
Created successful!
14576877
12677476
class ClassTest1
printMessage
class ClassTest1
main
class java.lang.Object
wait
class java.lang.Object
wait
class java.lang.Object
wait
class java.lang.Object
hashCode
class java.lang.Object
getClass
class java.lang.Object
equals
class java.lang.Object
toString
class java.lang.Object
notify
class java.lang.Object
notifyAll
2.TestClass.java
[java] view plain
/**
*
*/
public class TestClass {
public static void main(String[] args)
{
try {
// 测试Class.forName()
Class testTypeForName = Class.forName("TestClassType");
System.out.println("testForName---" + testTypeForName);
// 测试类名.class
Class testTypeClass = TestClassType.class;
System.out.println("testTypeClass---" + testTypeClass);
// 测试Object.getClass()
TestClassType testGetClass = new TestClassType();
System.out.println("testGetClass---" + testGetClass.getClass());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
class TestClassType {
// 构造函数
public TestClassType() {
System.out.println("----构造函数---");
}
// 静态的参数初始化
static {
System.out.println("---静态的参数初始化---");
}
// 非静态的参数初始化
{
System.out.println("----非静态的参数初始化---");
}
}
运行结果:
[plain] view plain
---静态的参数初始化---
testForName---class TestClassType
testTypeClass---class TestClassType
----非静态的参数初始化---
----构造函数---
testGetClass---class TestClassType
分析:根据结果可以发现,三种生成的Class对象一样的,并且三种生成Class对象只打印一次“静态的参数初始化”。
5. 关于用java反射调用一个类里面的方法并执行
Java中要用到反射,首先就必须要获取到对应的class对象,在Java中有三种方法获取类对应的class对象。
1、通过类的.class属性
2、通过类实例的getClass()方法获取
3、通过Class.forName(String className)方法获取
现在比如在package下有个类Calculator
publicclassCalculator{
publicdoubleadd(doublescore1,doublescore2){
returnscore1+score2;
}
publicvoidprint(){
System.out.println("OK");
}
publicstaticdoublemul(doublescore1,doublescore2){
returnscore1*score2;
}
}
publicclassCalculatorTest{
publicstaticvoidmain(String[]args)throwsException{
//通过类的.class属性获取
Class<Calculator>clz=Calculator.class;
//或者通过类的完整路径获取,这个方法由于不能确定传入的路径是否正确,这个方法会抛ClassNotFoundException
// Class<Calculator>clz=Class.forName("test.Calculator");
//或者new一个实例,然后通过实例的getClass()方法获取
// Calculators=newCalculator();
// Class<Calculator>clz=s.getClass();
//1.获取类中带有方法签名的mul方法,getMethod第一个参数为方法名,第二个参数为mul的参数类型数组
Methodmethod=clz.getMethod("mul",newClass[]{double.class,double.class});
//invoke方法的第一个参数是被调用的对象,这里是静态方法故为null,第二个参数为给将被调用的方法传入的参数
Objectresult=method.invoke(null,newObject[]{2.0,2.5});
//如果方法mul是私有的private方法,按照上面的方法去调用则会产生异常NoSuchMethodException,这时必须改变其访问属性
//method.setAccessible(true);//私有的方法通过发射可以修改其访问权限
System.out.println(result);//结果为5.0
//2.获取类中的非静态方法
Methodmethod_2=clz.getMethod("add",newClass[]{double.class,double.class});
//这是实例方法必须在一个对象上执行
Objectresult_2=method_2.invoke(newCalculator(),newObject[]{2.0,2.5});
System.out.println(result_2);//4.5
//3.获取没有方法签名的方法print
Methodmethod_3=clz.getMethod("print",newClass[]{});
Objectresult_3=method_3.invoke(newCalculator(),null);//result_3为null,该方法不返回结果
}
}
6. java 反射 调用无参数方法
通过Java反射调用无参数方法,这是个测试用的例子,通过反射调用对象的方法,代码如下:
importjava.lang.reflect.Method;
importjava.lang.reflect.InvocationTargetException;
/**
*CreatedbyIntelliJIDEA.
*File:TestRef.java
*User:Administrator
*Date:2015-7-1016:28:44
*/
publicclassTestRef{
publicstaticvoidmain(Stringargs[])throwsNoSuchMethodException,IllegalAccessException,InvocationTargetException{
Foofoo=newFoo("这个一个Foo对象!");
Classclazz=foo.getClass();
Methodm1=clazz.getDeclaredMethod("outInfo");
Methodm2=clazz.getDeclaredMethod("setMsg",String.class);
Methodm3=clazz.getDeclaredMethod("getMsg");
m1.invoke(foo);
m2.invoke(foo,"重新设置msg信息!");
Stringmsg=(String)m3.invoke(foo);
System.out.println(msg);
}
}
classFoo{
privateStringmsg;
publicFoo(Stringmsg){
this.msg=msg;
}
publicvoidsetMsg(Stringmsg){
this.msg=msg;
}
publicStringgetMsg(){
returnmsg;
}
publicvoidoutInfo(){
System.out.println("这是测试Java反射调用无参数方法的测试类");
}
}
控制台输出结果:
这是测试Java反射调用无参数方法的测试类
重新设置msg信息!
Processfinishedwithexitcode0
7. 如何通过java 反射 调用一个 含有 可变参数的 方法呢
java反射调用可变参数的方法的方式是传入objects参数,如下代码:
publicclassReflect{
publicstaticvoidmain(String[]args)throwsException{
Class<?>clazz=Single.class;
Singlesingle=(Single)clazz.newInstance();
List<String>list=newArrayList<String>(){
=1L;
{
add("fuck");
add("ni");
add("mei");
}
};
//获取method两种方式,在method中数组的的空间大小是可以随便写的不一定使用0
/*1*/
Methodmethod=clazz.getDeclaredMethod("method",Array.newInstance(Object.class,0).getClass());
/*2*/
method=clazz.getDeclaredMethod("method",(newObject[0]).getClass());//初始化参数
/*1*/
Objectobjs=Array.newInstance(Object.class,2);
Array.set(objs,0,list);
Array.set(objs,1,"23");
method.invoke(single,objs);
/*2*/
Object[]objects={1,"fuck",list};
method.invoke(single,newObject[]{objects});
}
}
classSingle{
publicvoidmethod(Object...objs){
System.out.println(Arrays.deepToString(objs));
}
}
结果:
[[fuck,ni,mei],23]
[1,fuck,[fuck,ni,mei]]
8. 如何通过反射调用有参构造函数
想通过反射调用有参构造函数,需要用到一个java类——Constructor。
Constructor提供关于类的单个构造方法的信息以及它的访问权限。
这我先建一个测试类。
package reflect;
import java.lang.reflect.Constructor;
class Person{
//两个属性
private String name;
private int age;
//假设有四种构造方法,一个无参构造方法,三个有参构造方法
public Person(){}
public Person(String name){
this.name=name;
}
public Person(int age){
this.age=age;
}
public Person(String name,Integer age){
this.name=name;
this.age=age;
}
@Overrride
public String toString(){
return "Person [age="+age+",name="+name+"]";
}
}
接下来主要说明怎么通过反射调用有参构造函数。
要调用有参构造函数一般已经知道该构造函数的参数类型和参数列表长什么样子了。
要做的就是拿到它,并通过它初始化实例。
package reflect;
public class Test{
public static void main(String args[]){
Class<?> demo =null;
try{
//通过反射声明Person
demo=Class.forName("reflect.Person");
}catch(Exception e){
e.printStackTrace();
}
//定义一个Person用来接收
Person per = null;
//关键来了---------------
Constructor<?> con=null; //声明一个Constructor
Class[] paramTypes={String.class,Integer.class}; //你要使用的有参构造函数中参数列表中的各个类型。
try{
con=demo.getConstrucetor(paramTypes);//通过类型获得构造方法的构造信息和访问权限
per=(Person)con.newInstance("Tom",20);//找到就可以使用了,传参实例化。
}catch(Exception e){
e.printStackTrace();
}
//-----------------------
System.out.println(per);
}
}
输出结果:Person [age=20,name=Tom]
9. JAVA反射中通过Class.forname()如何带参数的方法怎么赋值和调用呀
用Class.forName方法动态加载构造方法带参数的类。
10. java中,用反射方式调用一个类中的main方法
Main方法是用static修饰的,有种方法可以调用
1.类名.main(参数);
2.new创建实例,实例.main(参数);
这个地方注意必须传递字符串数组的参数 或者 null !
另外举一个用反射机制调用Main方法的例子
这个类是被调用的main方法类:
Java代码
public class Run
{
public static void main(String[] args)
{
String str=args[0]+"Hello World";
System.out.println(str);
}
}
下面是调用main方法的类:
Java代码
public class JobRun
{
public static void main(String[] args)
{
String idStr = "YAya";
try
{
Method method = Run.class.getMethod("main", String[].class);
method.invoke(null, (Object) new String[] { idStr });
}
catch (Exception e)
{
e.printStackTrace();
}
}
}