什么是反思,为什么它有用?
我对Java特别感兴趣,但我认为在任何语言中原则都是一样的.
是否有一个库将以递归方式转储/打印对象属性?我正在寻找类似于Firebug中的console.dir()函数的东西.
我知道commons-lang ReflectionToStringBuilder但它没有递归到一个对象.即,如果我运行以下内容:
public class ToString {
public static void main(String [] args) {
System.out.println(ReflectionToStringBuilder.toString(new Outer(), ToStringStyle.MULTI_LINE_STYLE));
}
private static class Outer {
private int intValue = 5;
private Inner innerValue = new Inner();
}
private static class Inner {
private String stringValue = "foo";
}
}
Run Code Online (Sandbox Code Playgroud)
我收到:
ToString $ Outer @ 1b67f74 [intValue = 5
innerValue = ToString $ Inner @ 530daa]
我意识到在我的例子中,我可以覆盖Inner的toString()方法,但在现实世界中,我正在处理我无法修改的外部对象.
我来自低级语言--C++是我编程的最高级别.
最近我遇到了Reflection,我无法理解如何在没有代码味道的情况下使用它.
在我看来,在运行期间检查类/方法/函数的想法指出了设计中的一个缺陷 - 我认为反射(试图)解决的大多数问题可以与多态性或正确使用继承一起使用.
我错了吗?我是否误解了反思的概念和效用?
我正在寻找一个很好的解释,说明何时使用Reflection,其他解决方案将失败或实现过于繁琐以及何时不使用它.
请指教这个低级别的笨蛋.
基于其缓慢的声誉,我总是避免使用Java反射.我在当前项目的设计中达到了一个重点,能够使用它会使我的代码更具可读性和优雅性,所以我决定试一试.
我对这种差异感到惊讶,有时候我注意到运行时间差了近100倍.即使在这个简单的例子中它只是实例化一个空类,它也令人难以置信.
class B {
}
public class Test {
public static long timeDiff(long old) {
return System.currentTimeMillis() - old;
}
public static void main(String args[]) throws Exception {
long numTrials = (long) Math.pow(10, 7);
long millis;
millis = System.currentTimeMillis();
for (int i=0; i<numTrials; i++) {
new B();
}
System.out.println("Normal instaniation took: "
+ timeDiff(millis) + "ms");
millis = System.currentTimeMillis();
Class<B> c = B.class;
for (int i=0; i<numTrials; i++) {
c.newInstance();
}
System.out.println("Reflecting instantiation took:"
+ timeDiff(millis) + "ms");
} …
Run Code Online (Sandbox Code Playgroud) 我正在使用Java版本的Google App Engine.
我想创建一个函数,可以接收许多类型的对象作为参数.我想打印出对象的成员变量.每个对象可能不同,并且该功能必须适用于所有对象.我必须使用反射吗?如果是这样,我需要编写什么样的代码?
public class dataOrganization {
private String name;
private String contact;
private PostalAddress address;
public dataOrganization(){}
}
public int getObject(Object obj){
// This function prints out the name of every
// member of the object, the type and the value
// In this example, it would print out "name - String - null",
// "contact - String - null" and "address - PostalAddress - null"
}
Run Code Online (Sandbox Code Playgroud)
我该如何编写函数getObject?
可能重复:
如何循环Java中的Class属性?
class Foo{
int id;
String name;
int bar;
int bar2;
//..
}
Foo foo = new Foo();
Run Code Online (Sandbox Code Playgroud)
有没有办法在java中迭代这个对象属性?我想创建一个INSERT查询,我必须转换字符串中的所有int属性.当有更多不同类型的属性时,这有点问题.
谢谢!
我想知道是否有一个较短的版本来检查我的 ProfileDto 的任何字段是否为空白。
在搜索互联网时,我只发现了有关如何检查某个字段是否为空或所有字段是否为空的问题,这是完全不同的。
对于上下文,如果为空,则应采用用户对象的相应字段(这只是对数据库的调用)。如果不为空,那么应该取ProfileDto字段
private void setEmptyFieldsForUpdatedUser(User user, ProfileDto profileDto) {
String newFirstName = profileDto.getFirstName();
String newLastName = profileDto.getLastName();
String newEmailAdres = profileDto.getEmail();
String oldPassword = profileDto.getPassword();
String newPassword = profileDto.getNewPassword();
if (newFirstName == null) {
profileDto.setFirstName(user.getFirstName());
}
if (newLastName == null) {
profileDto.setLastName(user.getLastName());
}
if (newEmailAdres == null) {
profileDto.setEmail(user.getEmail());
}
}
Run Code Online (Sandbox Code Playgroud)
这个 ProfileDto 给出了一个 JSON 对象。其中可以有空值。如果它为空,我想用数据库中的前一个用户字段设置该值。
我的数据库用户具有以下属性:
private void setEmptyFieldsForUpdatedUser(User user, ProfileDto profileDto) {
String newFirstName = profileDto.getFirstName();
String newLastName = profileDto.getLastName();
String newEmailAdres = profileDto.getEmail();
String …
Run Code Online (Sandbox Code Playgroud) 我想获取类实例的所有属性的名称和值。该类可以是任何自定义的任何类,它也可以具有对象列表、哈希图、表等,并且可以从另一个类扩展。实际上我的意思是我想获得一个类的所有属性的名称和值。所以我需要做的应该是一种模板。是否可以?到目前为止我已经写过了。任何建议将不胜感激。
public static void getObjectIntoMap(Object obj) throws IllegalArgumentException, IllegalAccessException {
Field[] field = obj.getClass().getDeclaredFields();
Class<?> c = obj.getClass().getSuperclass();
if(c != Object.class)
getObjectIntoMap(c.getClass());
System.out.println("SSS : "+field.length);
for (Field f : field) {
if(f.getType() == java.util.List.class){
java.util.List<Object> ll = (java.util.List<Object>) f.get(obj);
for (Object o : ll) {
Field[] ff = o.getClass().getDeclaredFields();
for (Field field2 : ff) {
print(field2.getName(), field2.get(o).toString());
}
}
}else if(f.getType() == Hashtable.class){
}
else if(f.getType() == HashMap.class){
}else if(f.getType() == Object[].class){
}
else{
print(f.getName(), f.get(obj).toString());
}
}
}
Run Code Online (Sandbox Code Playgroud) 在Ruby中,我可以使用以下代码获取实例变量val
class C
def initialize(*args, &blk)
@iv = "iv"
@iv2 = "iv2"
end
end
puts "C.new.inspect:#{C.new.inspect} ---- #{::File.basename __FILE__}:#{__LINE__}"
# => C.new.inspect:#<C:0x4bbfb90a @iv="iv", @iv2="iv2"> ---- ex.rb:8
Run Code Online (Sandbox Code Playgroud)
在Java中,我希望我能得到以下结果,我该怎么办?
package ro.ex;
public class Ex {
String attr;
String attr2;
public Ex() {
this.attr = "attr";
this.attr2 = "attr2";
}
public static void main(String[] args) {
new Ex().inspect();
// => Ex attr= "attr", attr2 = "attr2";
}
}
Run Code Online (Sandbox Code Playgroud)
更新:
我发现这可以解决我的问题,但我想更简单,像guava.in ruby中的一些函数,我主要在rubymine监视工具窗口中使用Object#inspect,我希望我可以像obj.inspect一样使用它
更新:
我终于确定使用Tedy Kanjirathinkal的答案,我自己用以下代码实现:
package ro.ex;
import com.google.common.base.Functions;
import com.google.common.collect.Iterables;
import …
Run Code Online (Sandbox Code Playgroud) java ×8
reflection ×5
database ×1
dump ×1
performance ×1
properties ×1
ruby ×1
terminology ×1
tostring ×1