Java反射 在只知道类名的情况下,怎样给其中的私有属性赋值
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java反射 在只知道类名的情况下,怎样给其中的私有属性赋值相关的知识,希望对你有一定的参考价值。
只知道类名,就是不能通过导入访问这个类
利用反射能
//假设类名为A// 实例化类
A p = new A();
// 获取class
Class c = p.getClass();
// 获取该类所有的字段
Field[] fields = c.getDeclaredFields();
// 遍历赋值
for (int i = 0; i < fields.length; i++)
String filedName = fields[i].getName();
// AccessibleTest类中的成员变量为private,故必须进行此操作
fields[i].setAccessible(true);
// 判断类型
Class<?> type=fields[i].getType();
//获取字段类型
String typeName=type.getName();
System.out.println(type.getName());
// 对字段进行赋值 第一个参数为对象引用第二个参数为要附的值
//如果为字符串类型
if("java.lang.String".equals(typeName))
fields[i].set(p, "1");
//如果为日期类型
else if("java.util.Date".equals(typeName))
fields[i].set(p, new Date());
else
fields[i].set(p, 1);
//楼主我只是简单的写了下。可能还需要判断字段名称以及其他类型什么的。
最后希望楼主多看看java 文档。
参考技术A /*** Field的反射与对私有变量的暴力反射。
* 当通过一个实例对象拿到相应的字段对象时,他代表的是所有该类型的字段,不是一个具体实例的该字段,因为
* 他境界提高了
*/
ReflectPoint pt1=new ReflectPoint(5,4);
//对于普通公共成员的反射
Field fieldy=pt1.getClass().getField("y");
System.out.println(fieldy.get(pt1));
//对于私有成员的暴力反射,暴力反射要解决的两个问题,1获得看不见的成员,2 看见了还要设置这个成员是可以被访问的。
Field fieldx=pt1.getClass().getDeclaredField("x");
fieldx.setAccessible(true);
System.out.println(fieldx.get(pt1));
changeStringValue(pt1);
System.out.println(pt1); 参考技术B 给私有属性赋值,就调用它的setter方法啊! 参考技术C 泛型,反射赋值
具体说一下你的情况,贴出的你代码。
C#中的反射
一:什么是反射
C#编写的程序会编译成一个程序集(.DLL或.exe),其中会包含元数据、编译代码和资源,通过反射可以获取到程序集中的信息
通俗来讲,反射就是我们在只知道一个对象的外部而不了解内部结构的情况下,可以知道这个对象的内部实现
二:反射的优缺点
首先在编译中分为动态编译和静态编译,静态编译是在编译中确定类型,绑定对象,而动态编译是在运行中确定类型,绑定对象
反射的优点就是可以动态创建对象、绑定对象,提高了程序的灵活性和扩展性,但反射是一种解释操作,在性能上不如静态编译快
三:通过Type类获取程序集、模块、类的相关信息
——Type类是一个抽象类,因此不能用他去实例化对象
——object类中定义了一个GetType方法,因此所有类都可以使用GetType()获取到某一个对象所属类的Type对象
——通过Type对象可以获取到类中字段、属性、方法、构造函数等信息
using System;
class MainClass
{
public static void Main(string[] args)
{
//1.通过对象获取到这个对象所属类的Type对象
TestClass c = new TestClass();
Type t = c.GetType();
//2.通过Type类中的静态方法GetType获取到类的Type对象
//Type t = Type.GetType("TestClass");
//3.通过typeof关键字获取到类的Type对象
//Type t = typeof(TestClass);
Console.WriteLine(t.Name);//获取类名(不带命名空间)
Console.WriteLine(t.FullName);//获取类名(带命名空间)
Console.WriteLine(t.Assembly);//获取程序集
Console.WriteLine(t.BaseType);//获取基类类型
Console.WriteLine("----------获取类中字段");
var fields = t.GetFields();
foreach (var temp in fields)
{
Console.WriteLine(temp.Name);
}
Console.WriteLine("----------获取类中属性");
var properties = t.GetProperties();
foreach (var temp in properties)
{
Console.WriteLine(temp.Name);
}
Console.WriteLine("----------获取类中方法");
var methods = t.GetMethods();
foreach (var temp in methods)
{
Console.WriteLine(temp.Name);
}
Console.WriteLine("----------获取类中成员");
var members = t.GetMembers();
foreach (var temp in members)
{
Console.WriteLine(temp.Name);
}
Console.WriteLine("----------获取类中嵌套类");
var nesteds = t.GetNestedTypes();
foreach (var temp in nesteds)
{
Console.WriteLine(temp.Name);
}
Console.WriteLine("----------获取类中构造函数");
var constructors = t.GetConstructors();
foreach (var temp in constructors)
{
Console.WriteLine(temp.Name);
}
}
}
public class TestClass
{
public string str;
public int num { get; set; }
public void Fun()
{
}
public class TestNestedClass
{
}
}
得到一个Type类型对象有三种方法:object.GetType()、Type.GetType()、typeof()
使用object.GetType()必须先创建一个实例,而后两种不需要创建实例,但使用typeof运算符仍然需要知道类型的编译时信息,Type.GetType()静态方法不需要知道类型的编译时信息,所以是首选方法
四:创建实例:性能上要比new差
——通过Activator创建实例
using System;
class MainClass
{
public static void Main(string[] args)
{
object c = Activator.CreateInstance(typeof(TestClass), "hello world");
Console.WriteLine(((TestClass)c).str);
}
}
public class TestClass
{
public string str;
public TestClass(string str)
{
this.str = str;
}
}
——通过构造函数创建实例
using System;
class MainClass
{
public static void Main(string[] args)
{
Type t = typeof(TestClass);
Type[] paramTypes = new Type[1] { typeof(string) };
var info = t.GetConstructor(paramTypes);
object[] param = new object[1] { "hello world" };
var o = info.Invoke(param);
Console.WriteLine(((TestClass)o).str);
}
}
public class TestClass
{
public string str;
public TestClass(string str)
{
this.str = str;
}
}
五:反射赋值
using System;
using System.Reflection;
class MainClass
{
public static void Main(string[] args)
{
TestClass cc = new TestClass();
Type t = cc.GetType();
FieldInfo info = t.GetField("str");
info.SetValue(cc, "hello world");
Console.WriteLine(info.GetValue(cc));
}
}
public class TestClass
{
public string str;
}
以上是关于Java反射 在只知道类名的情况下,怎样给其中的私有属性赋值的主要内容,如果未能解决你的问题,请参考以下文章