java问题,动态修改java类里面的一个方法

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java问题,动态修改java类里面的一个方法相关的知识,希望对你有一定的参考价值。

由于项目中有很多try catch中都是写e.printstacktrace(); 现在由于项目需要做错误日志记录记录功能,由于try catch很多,不想以一个一个在里面加代码,有没有办法通过增强e.printstacktrace这个方法,在printstacktrace()里面做手脚,在方法的最后执行我的日志记录方法呢

参考技术A //创建文件输出流
PrintStream ps=new PrintStream("./log.txt");
//设置新的输出流 System.setErr(ps);

System类的out、err、in成员变量都是final类型的,不能直接复制,要通过setOut()、setErr(),setIn()方法来改变流。上例是通过setOut()方法改变输入流输入位置,将输出重定向到一个固定的目录,实现程序日志
e.printstacktrace 默认用的就是System的输出追问

这个一设置可以全局就设置好了?

参考技术B public class PersistenceException 
    public PersistenceException(Exception e)
        // 这里对错误信息进行持久化
        System.out.println("持久化代码放这里...");
        // 如果需要在控制台同时打印出日志的话
        e.printStackTrace();
    
    /**测试主方法*/
    public static void main(String[] args)
        int a = 0;
        int b = 0;
        try 
            int c = a/b;
        catch (Exception e)
            new PersistenceException(e);
        
    

参考技术C AST 修改抽象语法树 参考技术D 不管如何,都是需要逐个改,不如一次修改好。。。。。。。。。追问

请问有什么办法可以动态改吗?

Java编程基础-反射

一、java反射

1、反射:动态获取类的信息,以及动态调用对象的方法的功能。可以理解为动态看透类的能力。

2、主要功能:在运行时判断任意一个对象所属的类;在运行时构造任意一个类的对象;在运行时判断任意一个类所具有的成员变量和方法;在运行时调用任意一个对象的方法;生成动态代理。

通过Java反射机制,可以在程序中访问已经装载到JVM中的java对象的描述,实现访问、检测和修改描述java对象本身信息的功能。java反射机制的功能十分强大,java.lang.reflect包中提供了对该功能的支持。


二、通过反射获取类的三种方法

  1. //1、第一种方式-->Class.forName("类名字符串");  
  2.         //注:类名字符串是"包名+类名" 返回Class的对象。(这种是最常用的方法)  
  3.         Class c1=Class.forName("csdn.Student");  
  4.         //2、第二种方式-->先创建对象,再用对象调用getClass()方法,即实例对象.getClass().返回运行时类。  
  5.         //任何一个java对象都有getClass()方法  
  6.         Student s=new Student();  
  7.         Class c2 = s.getClass();  
  8.         //3、第三种方式-->类名.class。返回Class的对象。(每个类都有class属性)  
  9.         Class c3=Student.class;  

 

三、通过反射可以获取到的主要描述信息

技术分享技术分享

  1. package csdn;  
  2.   
  3. public class Person {  
  4.     public String name;// 姓名  
  5.     public int age;// 年龄  
  6.   
  7.     public Person() {  
  8.         super();  
  9.     }  
  10.   
  11.     public Person(String name, int age) {  
  12.         super();  
  13.         this.name = name;  
  14.         this.age = age;  
  15.     }  
  16.   
  17.     public String showInfo() {  
  18.         return "name=" + name + ", age=" + age;  
  19.     }  
  20. }  


子类:Student类

  1. package csdn;  
  2.   
  3. public class Student extends Person implements Study {  
  4.     public String className;// 班级  
  5.     private String address;// 住址  
  6.   
  7.     public Student() {  
  8.         super();  
  9.     }  
  10.   
  11.     public Student(String name, int age, String className, String address) {  
  12.         super(name, age);  
  13.         this.className = className;  
  14.         this.address = address;  
  15.     }  
  16.   
  17.     public Student(String className) {  
  18.         this.className = className;  
  19.     }  
  20.   
  21.     public String toString() {  
  22.         return "姓名:" + name + ",年龄:" + age + ",班级:" + className + ",住址:"  
  23.                 + address;  
  24.     }  
  25.   
  26.     public String getAddress() {  
  27.         return address;  
  28.     }  
  29.   
  30.     public void setAddress(String address) {  
  31.         this.address = address;  
  32.     }  
  33.   
  34. }  

接口:study
  1. package csdn;  
  2.   
  3. public interface Study {  
  4.     //仅为了演示获得接口,就没有写抽象方法  
  5. }  
1、获得属性:
  1. Class stu = Class.forName("csdn.Student");  
  2.             // 获取对象的所有公有属性。  
  3.             Field[] fields = stu.getFields();  
  4.             for (Field f : fields) {  
  5.                 System.out.println(f);  
  6.             }  
  7.             System.out.println("---------------------");  
  8.             // 获取对象所有属性,但不包含继承的。  
  9.             Field[] declaredFields = stu.getDeclaredFields();  
  10.             for (Field ff : declaredFields) {  
  11.                 System.out.println(ff);  
  12.             }  
运行结果:
public java.lang.String csdn.Student.className
public java.lang.String csdn.Person.name
public int csdn.Person.age
---------------------
public java.lang.String csdn.Student.className
private java.lang.String csdn.Student.address

2、获得方法:
  1. Class stu = Class.forName("csdn.Student");  
  2.             // 获取对象的所有公共方法  
  3.             Method[] methods = stu.getMethods();  
  4.             for (Method m : methods) {  
  5.                 System.out.println(m);  
  6.             }  
  7.             System.out.println("---------------------");  
  8.             // 获取对象所有方法,但不包含继承的  
  9.             Method[] declaredMethods = stu.getDeclaredMethods();  
  10.             for (Method ms : declaredMethods) {  
  11.                 System.out.println(ms);  
  12.             }  
运行结果:
public java.lang.String csdn.Student.toString()
public java.lang.String csdn.Student.getAddress()
public void csdn.Student.setAddress(java.lang.String)
public java.lang.String csdn.Person.showInfo()
public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException
public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException
public final void java.lang.Object.wait() throws java.lang.InterruptedException
public boolean java.lang.Object.equals(java.lang.Object)
public native int java.lang.Object.hashCode()
public final native java.lang.Class java.lang.Object.getClass()
public final native void java.lang.Object.notify()
public final native void java.lang.Object.notifyAll()
---------------------
public java.lang.String csdn.Student.toString()
public java.lang.String csdn.Student.getAddress()
public void csdn.Student.setAddress(java.lang.String)


3、获得构造方法:

为了演示区别,将Student类中参数为className的构造方法的public修饰符改为protected,查看效果。
  1. Class stu = Class.forName("csdn.Student");  
  2.             // 获取对象所有的公共构造方法  
  3.             Constructor[] constructors = stu.getConstructors();  
  4.             for (Constructor c : constructors) {  
  5.                 System.out.println(c);  
  6.             }  
  7.             System.out.println("---------------------");  
  8.             // 获取对象所有的构造方法  
  9.             Constructor[] declaredConstructors = stu.getDeclaredConstructors();  
  10.             for (Constructor con : declaredConstructors) {  
  11.                 System.out.println(con);  
  12.             }  
运行结果为:
public csdn.Student(java.lang.String,int,java.lang.String,java.lang.String)
public csdn.Student()
---------------------
protected csdn.Student(java.lang.String)
public csdn.Student(java.lang.String,int,java.lang.String,java.lang.String)
public csdn.Student()


4、获得其他:
  1. Class stu = Class.forName("csdn.Student");  
  2.             System.out.println(stu.getName());//获取对象全限定名称  
  3.             System.out.println(stu.getPackage());// 获取包名  
  4.             Class[] interfaces = stu.getInterfaces();//获取该类实现的所有接口  
  5.             for(Class in:interfaces){  
  6.                 System.out.println(in);  
  7.             }  
运行结果为:
csdn.Student
package csdn
interface csdn.Study

5、通过反射实例化对象,调用对象方法
  1. package csdn;  
  2.   
  3. import java.lang.reflect.Constructor;  
  4. import java.lang.reflect.Method;  
  5.   
  6. public class TestReflect {  
  7.   
  8.     @SuppressWarnings("unchecked")  
  9.     public static void main(String[] args)  {  
  10.         try {  
  11.             Class c = Class.forName("csdn.Student");  
  12.             Student stu = (Student) c.newInstance();  
  13.             // 第一种方法,实例化默认构造方法,调用set赋值  
  14.             stu.setAddress("深圳南山");  
  15.             System.out.println(stu);  
  16.             // 第二种方法 取得全部的构造函数 使用构造函数赋值  
  17.             Constructor<Student> constructor = c.getConstructor(String.class,  
  18.                     int.class, String.class, String.class);  
  19.             Student s = (Student) constructor.newInstance("李四", 18, "七班", "深圳");  
  20.             System.out.println(s);  
  21.   
  22.             Method show = c.getMethod("showInfo");//获取showInfo()方法  
  23.             System.out.println(show.invoke(s));//调用showInfo()方法  
  24.   
  25.         } catch (Exception e) {  
  26.   
  27.             e.printStackTrace();  
  28.         }  
  29.     }  
  30. }<span style="color:#3333ff;"><strong>  
  31. </strong></span>  
运行结果为:
姓名:null,年龄:0,班级:null,住址:深圳南山
姓名:李四,年龄:18,班级:七班,住址:深圳
name=李四, age=18













































以上是关于java问题,动态修改java类里面的一个方法的主要内容,如果未能解决你的问题,请参考以下文章

Java静态方法获取所属类的信息

java可以动态加载一个jar包,并且调用里面的类和方法吗?

Java中的反射

java反射

java里面import java.util.*;是啥用处?

java 导出jar包,类里面用到了第三方jar包,不可用