反射机制有什么用
可以操作字节码文件
反射机制的相关类再哪个包下?
java.lang.reflect.*;
反射机制相关的类
java.lang.Class 代表字节码文件
java.lang.reflect.Method 代表字节码中的方法的字节码
java.lang.reflect.Constructor 代表字节码中的构造器的字节码
java.lang.reflect.Field 代表字节码中的属性的字节码
利用反射机制操作字节码文件
获取类的字节码
第一种方式:使用静态方法Class.forName(完整类名加包名)
Class c1 = Class.forName("java.lang.String");
Class.forName("java.lang.String");会导致类加载,即执行一次,String方法中的静态代码块也会执行一次,如果想一个类的静态方法执行一次,那么可以使用Class.forName()
第二种方式:使用Object类中的引用.getClass()方法
String s = "abc";
Class c = s.getClass();
第三种方式:java中的任意数据类型(包括基本数据类型)都有class属性
Class c = String.class;
Class c = int.class;
通过字节码文件来实例化对象
public class Test {
public static void main(String[] args) {
Class c = null;
try {
//通过反射机制获取字节码文件
c = Class.forName("User");
//newInstacnce()方法会调用User的无参构造方法来new一个User对象
//必须保证User的无参构造方法存在!
Object o = c.newInstance();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
}
}
}
class User{
}
注意:使用这种方法来初始化对象,更灵活!
举个例子
配置文件
//classinfo.Properties
className=com.sdut.wwg.User
User类
package com.sdut.wwg;
public class User {
@Override
public String toString() {
return "User{}";
}
}
Test类
import java.io.FileReader;
import java.util.Properties;
public class Test {
public static void main(String[] args) throws Exception{
//还可以这样获取绝对路径
/*
String path = Thread.currentThread().getContextClassLoader()
.getResource("classinfo.Properities").getPath();
还可以直接返回一个流
InputStream r =Thread.currentThread().getContextClassLoader()
.getResourceAsStream("classinfo.Properities");
*/
FileReader r = new FileReader("Demo/src/classinfo.Properities");
Properties p = new Properties();
p.load(r);
r.close();
String className = p.getProperty("className");
//通过反射机制获取字节码文件
Class c= Class.forName(className);
//newInstacnce()方法会调用User的无参构造方法来new一个User对象
//必须保证User的无参构造方法存在!
Object o = c.newInstance();
System.out.println(o);
}
}
这样的优点在于当服务器运行的时候,可以直接修改配置文件,而不需要改代码情况下可以做到不同对象的实例化
反射属性
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws Exception{
Class c = Class.forName("com.sdut.wwg.User");
//获取完整类名
System.out.println("完整类名为"+c.getName());
System.out.println("简类名为"+c.getSimpleName());
//获取User所有的公共属性
Field[] fs = c.getFields();
System.out.println("所有声明公有属性数量总计"+fs.length);
//获取User所有的属性
Field[] allFs = c.getDeclaredFields();
System.out.println("所有声明属性数量总计"+allFs.length);
System.out.println("属性名为:");
for (int i = 0; i <allFs.length ; i++) {
System.out.println(allFs[i].getName());
}
System.out.println("各属性类型为:");
for (int i = 0; i <allFs.length ; i++) {
//获取属性修饰符
int s = allFs[i].getModifiers();
System.out.println(s);
//可以将这个代号数字转换为字符串
String modifierString = Modifier.toString(s);
System.out.println(modifierString);
//获取属性的类型
Class fieldType = allFs[i].getType();
System.out.println(fieldType.getSimpleName());
}
}
}
通过反射机制来反编译一个类的属性(了解)
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws Exception{
Class c = Class.forName("User");
StringBuffer s= new StringBuffer();
//获取类的修饰符列表和类名
s.append(Modifier.toString(c.getModifiers())+" class "+c.getSimpleName()+"{\n");
Field[] fields = c.getDeclaredFields();
for(Field f:fields){
s.append("\t");
s.append(Modifier.toString(f.getModifiers())+" ");
s.append(f.getType().getSimpleName()+" ");
s.append(f.getName()+";\n");
}
s.append("}");
System.out.println(s);
}
}
输出结果为

通过访问机制来访问一个java对象的属性
import java.lang.reflect.Field;
public class Test {
public static void main(String[] args) throws Exception{
Class c = Class.forName("User");
Object o = c.newInstance();
//获取no属性
Field noField = c.getDeclaredField("no");
//给o对象的no属性赋值
noField.set(o,1111);
//读取属性的值
System.out.println(noField.get(o));
//可以访问私有属性吗??
Field nameField = c.getDeclaredField("name");
//需要打破封装.这样设置完之后,在外部也是可以访问私有属性的
nameField.setAccessible(true);
nameField.set(o,"jack");
System.out.println(nameField.get(o));
}
}
反射方法
public class Test {
public static void main(String[] args) throws Exception{
Class c = Class.forName("User");
//获取所有的方法
Method[] methods = c.getDeclaredMethods();
//获取获取到的方法数量
System.out.println(methods.length);
for(Method m:methods){
//输出方法的修饰符列表
System.out.print(Modifier.toString(m.getModifiers())+" ");
//输出方法的返回值类型
System.out.print(m.getReturnType().getSimpleName()+" ");
//输出方法的名字
System.out.println(m.getName());
//获取参数
Class [] ctypes = m.getParameterTypes();
for(Class clas: ctypes){
//输出参数的类型
System.out.println(clas.getSimpleName());
}
}
}
}
反编译方法名和参数列表
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
public class Test {
public static void main(String[] args) throws Exception{
StringBuffer s = new StringBuffer();
Class c = Class.forName("java.lang.String");
Method [] methods = c.getDeclaredMethods();
for(Method m: methods){
s.append('\t');
s.append(Modifier.toString(m.getModifiers())+" "+m.getReturnType().getSimpleName()+" "+m.getName());
s.append(" (");
Class []classes = m.getParameterTypes();
for(Class cls : classes){
s.append(cls.getSimpleName()+',');
}
if(classes.length>0)
s.deleteCharAt(s.length()-1);
s.append(") { }\n");
}
System.out.println(s);
}
}
输出结果为

通过反射机制调用方法
import java.lang.reflect.Method;
public class Test {
public static void main(String[] args) throws Exception{
Class userClass = Class.forName("User");
//创建一个User类对象
Object o = userClass.newInstance();
//获取sum方法
Method sum = userClass.getDeclaredMethod("sum", int.class, int.class);
//调用sum方法
int result =(int)sum.invoke(o,1,2);
System.out.println(result);
}
}
通过反射机制调用有参构造方法
import java.lang.reflect.Constructor;
public class Test {
public static void main(String[] args) throws Exception{
Class userClass = Class.forName("User");
//调用无参构造方法创建对象
Object o = userClass.newInstance();
//调用有参构造方法创建对象
Constructor constructor = userClass.getConstructor(int.class,String.class);
Object o1 = constructor.newInstance(1111,"jack");
System.out.println(o);
System.out.println(o1);
}
}
输出结果为

通过反射机制获取父类以及实现了什么接口
public class Test {
public static void main(String[] args) throws Exception{
Class stringClass = Class.forName("java.lang.String");
//获取父类名
Class superClass = stringClass.getSuperclass();
System.out.println(superClass.getSimpleName());
//获取实现了什么接口
Class[] interfaces = stringClass.getInterfaces();
for(Class i:interfaces){
System.out.println(i.getSimpleName());
}
}
}
输出结果

1万+

被折叠的 条评论
为什么被折叠?



