字节一面,面试官拿System.out.println()考了我半个小时?我懵逼了...

本文深入剖析Java中System.out.println()的内部机制,从System类到PrintStream对象,再到println方法的重载原理,带你全面理解面向对象编程在Java中的具体应用。

之前春招面试我被问及,你如何理解System.out.println() ?

今天我就来给大家分享一下!

学了这么久的面向对象编程,那如何用一行代码体现呢?

如果你能自己读懂System.out.println(),就真正了解了Java面向对象编程的含义

面向对象编程即创建了对象,所有的事情让对象帮亲力亲为(即对象调用方法)

System.out.println("hello world");
hello world

Process finished with exit code 0

首先分析System源码

System就是Java自定义的一个类

out源码分析

①out是System里面的一个静态数据成员,而且这个成员是java.io.PrintStream类的引用

②out已经存在了且用Static修饰了,所以可以直接使用类名+属性名的方式调用,也就是System.out。

println分析

①println()就是java.io.PrintStream类里的一个方法,它的作用是向控制台输出信息。

②里面有很多重载的方法,这样就保证了任意的东西都可以输出

小结下来就是:类调用对象,对象调用方法

拓展知识点 :

1.System.out.print();与System.out.println(); 的区别

  • 2.字符数组输出面试案例

public class Demo {

    public static void main(String[] args) {
        char[] ch=new char[]{'x','y'};
        System.out.println(ch);

        char[] ch1=new char[]{'x','y'};
        System.out.println("ch1="+ch1);
    }
}
xy
ch1=[C@74a14482

这是println()方法的重载,java打印输出System.out.println会自动调用输入参数的toString方法,输出内容时toString方法的返回值。

println的参数分基本类型,一个是String 另一个是Object类型。

System.out.println(ch) println()自动调用println(char[] ) 也就是Object类型 所以输出xy

然而System.out.println(“ch=”+ch) "+"是字符串连接符,自动调用println(String ),也就是String类型 输出的是xxx@xxxx的形式。

详细理解 逐步进入之后,发现调用toString() ,我们可以进行重写。

作者:阿博的Java栈
来源:http://suo.im/5wTHK0
### 静态代理与动态代理的区别 #### 生成时机 静态代理在编译时就已经实现,编译完成后代理类是一个实际的class文件。这意味着开发者需要手动编写代理类,并且其结构固定[^3]。例如: ```java public class StaticProxy implements Service { private RealService realService; public StaticProxy(RealService realService) { this.realService = realService; } @Override public void performAction() { System.out.println("Before action"); realService.performAction(); System.out.println("After action"); } } ``` 而动态代理是在运行时动态生成的,即编译完成后没有实际的class文件,而是在运行时动态生成类字节码,并加载到JVM中。Java 的动态代理机制是基于反射实现的,通过使用 `java.lang.reflect.Proxy` 类和 `java.lang.reflect.InvocationHandler` 接口来实现动态代理 [^2]。 ```java public class DynamicProxyFactory { public static Object getProxy(Object target) { return Proxy.newProxyInstance( target.getClass().getClassLoader(), target.getClass().getInterfaces(), (proxy, method, args) -> { System.out.println("Before method call"); Object result = method.invoke(target, args); System.out.println("After method call"); return result; } ); } } ``` #### 灵活性 静态代理的目标角色固定,代理对象会增强目标对象的行为。这种方式适用于小型项目或代理类相对固定的场景。然而,如果接口发生变化,需要重新修改代理类,维护成本较高。 动态代理的目标对象不固定,代理对象在应用程序执行时动态创建。这种灵活性使得动态代理适用于需要动态扩展功能或减少重复代码的场景。例如,Spring AOP 使用动态代理来实现日志记录、事务管理等功能,无需为每个方法单独编写代理类 [^2]。 #### 实现原理 静态代理的实现较为简单,主要依赖于接口和具体的实现类。代理类和被代理类都实现了相同的接口,代理类持有被代理类的引用,并在其基础上添加额外逻辑 [^1]。 动态代理的核心在于 `Proxy` 类和 `InvocationHandler` 接口。`Proxy.newProxyInstance()` 方法用于创建一个代理对象,该对象将方法调用委托给 `InvocationHandler` 实现类。`invoke` 方法会在代理对象的方法被调用时执行,从而可以统一处理前置和后置操作 [^3]。 ```java public class ServiceInvocationHandler implements InvocationHandler { private Object target; public ServiceInvocationHandler(Object target) { this.target = target; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("Before invoking method"); Object result = method.invoke(target, args); System.out.println("After invoking method"); return result; } } ``` #### 应用场景 静态代理适用于小型项目或代理类相对固定的场景。由于其实现简单,适合不需要频繁修改代理逻辑的情况。例如,在教学示例中展示代理模式的基本概念时,静态代理是一种直观的选择 [^3]。 动态代理适用于需要动态扩展功能或减少重复代码的场景。例如,框架开发中经常使用动态代理来实现通用的功能拦截,如权限控制、缓存管理等。Spring 框架中的 AOP(面向切面编程)就是基于动态代理实现的,能够在不修改业务代码的情况下增强方法行为 。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值