cuiter  

一、面向对象上

1、构造器不是没有返回值吗?为啥不能用void声明呢?

​ 理由:实际上类的构造器是有返回值的,当使用new关键字调用构造器时,构造器将会返回这个类的实例,因此构造器的返回值类型总是当前类,但不要在构造器中显式return来返回当前类的对象,因为Java规定构造器的返回值是隐式的。

2、为什么规定静态成员不能直接访问非静态成员?

​ 理由1:static修饰的成员,是用类作为主调,如果static方法中使用this关键字引用,那么this无法指向合适的对象,所以static方法中不能使用this引用,所有static修饰的方法中不能访问不使用static修饰的普通成员;而且Java编程时,尽量不要使用对象调用static的成员,而是用类去调用,因为就算用对象去调用,底层实现仍然是类在调用。

​ 理由2:静态成员属于类,作用域比非静态成员大,完全可能出现静态成员已经初始化完成,但非静态成员还没有初始化的情况,如果允许静态成员访问非静态成员将会引起大量错误。

3、为什么说Java语言是静态的?

​ 理由:一个类定义完成后,只要不再重新编译这个类文件,该类和该类的对象所拥有的方法是固定的,永远不会变。

4、Java的方法参数传递方式是怎样的?

​ 解答:值传递,更细致一点说是栈值传递。为什么这么说呢?可从下面程序知道,创建对象时,系统内存中有两个东西,堆内存中保存了对象本身,栈内存保存了引用该对象的引用变量,传参时将栈值赋值过去。

class DataWrap
{
	int a;
	int b;
}
public class ReferenceTransferTest
{
	public static void swap(DataWrap dw)
	{
		// 下面三行代码实现dw的a、b两个成员变量的值交换。
		// 定义一个临时变量来保存dw对象的a成员变量的值
		var tmp = dw.a;
		// 把dw对象的b成员变量值赋给a成员变量
		dw.a = dw.b;
		// 把临时变量tmp的值赋给dw对象的b成员变量
		dw.b = tmp;
		System.out.println("swap方法里,a成员变量的值是"
			+ dw.a + ";b成员变量的值是" + dw.b);
		// 把dw直接赋为null,让它不再指向任何有效地址。
		dw = null;
	}
	public static void main(String[] args)
	{
		var dw = new DataWrap();
		dw.a = 6;
		dw.b = 9;
		swap(dw);
		System.out.println("交换结束后,a成员变量的值是"
			+ dw.a + ";b成员变量的值是" + dw.b);
        // swap方法里,a成员变量的值是9;b成员变量的值是6
        // 交换结束后,a成员变量的值是6;b成员变量的值是9
	}
}

5、对于个数可变的形参来说,只能处于形参列表的最后,并且只能有一个;其实本质上就是一个数组类型的形参,因此个数可变的形参可以传入多个参数或者一个数组。

	// 定义了形参个数可变的方法
	public static void test(int a, String... books)
	{
		// books被当成数组处理
		for (var tmp : books)
		{
			System.out.println(tmp);
		}
		// 输出整数变量a的值
		System.out.println(a);
	}
	public static void main(String[] args)
	{
		// 调用test方法  多个参数分别传
		test(5, "疯狂Java讲义", "轻量级Java EE企业应用实战");
         // 传入数组
         test(23, new String[]{"疯狂Java讲义", "轻量级Java EE企业应用实战"});
	}

6、方法重载,两同一不同:同一个方法名相同,参数列表不同。

7、为什么返回值类型不能用于区分重载的方法?

​ 理由:对于int f(){}和void f(){}两个方法,如果这样调用int result = f();,系统可以识别调用的是int f(){},但如果调用方法时忽略返回值,直接这样调用f();,那么系统就不知道你调用的哪个方法了。

8、访问控制符,private(同一类中)—>default(同一包中)—>protected(同一包及其不同包子类)—>public(全局范围)

9、package必须作为源文件第一条非注释性语句,因此一个类只能指定一个包。

10、静态导入使用import static,简单来说:使用import可以省略不写包名,使用import static可以省略不写类名,但是只能使用静态成员。

import static java.lang.System.*;
import static java.lang.Math.*;


public class StaticImportTest
{
	public static void main(String[] args)
	{
		// out是java.lang.System类的静态成员变量,代表标准输出
		// PI是java.lang.Math类的静态成员变量,表示π常量
		out.println(PI);
		// 直接调用Math类的sqrt静态方法
		out.println(sqrt(256));
	}
}

11、构造器是创建Java对象的途径,是不是说构造器完全负责创建Java对象呢?

​ 解答:不是,构造器是创建Java对象的重要途经,通过new关键字调用构造器也确实返回了该类对象,但这个对象并不是完全由构造器创建的;事实上,当程序员调用构造器时,系统会先为该对象分配内存空间,并为这个对象执行默认初始化,这个对象已经产生了,这些操作都是在构造器执行前完成的,只是不能被外界访问。当构造器执行体执行后,这个对象会被构造器返回,从而让外部访问。

12、Java是单继承的,也就是说Java只有一个直接父类;子类只能从被扩展的父类获得成员变量、方法和内部类,不能获得构造器和代码块。

13、方法重写,两同两小一大:方法名相同、形参列表不同、子类返回值类型比父类返回值小或者相等、子类异常类型比父类返回值小或相等、子类访问权限比父类访问权限大或者相等;重写和被重写的方法不能一个是类方法、一个是实例方法。

14、子类定义了一个与父类private方法具有相同的方法名、形参列表、返回值类型、异常类型的方法依旧不是重写;子类定义一个与父类非private方法有相同的方法但参数列表不同的方法就会形成父类方法和子类方法的重载。

15、this、super不能出现在static修饰方法中。因为static的主调是类,而不是对象,因此super就没有指定实例。

16、在子类定义的实例方法中可以通过super来访问父类私有成员。

17、若是父类没有无参构造器,子类构造器必须显式调用父类构造器。

18、多态的产生:编译时类型由声明该变量时使用的类型觉定,运行时类型由实际赋给该变量的对象决定。如果编译时类型和运行时类型不一致,就可能出现所谓的多态;相同类型的变量调用同一个方法时呈现出不同的行为特征就是多态。(对象的实例变量不具备多态)

19、instanceof运算符前面操作数的编译时类型要么与后面的类相同,要么与后面的类具有父子继承关系,否则会引起编译错误。其作用是在强制类型转换之前判断前一个对象是否是后一个类的实例,是否可以成功转换,从而保证代码更加健壮。

20、链式编程的一种实现

/**
 * <p>
 *     统一返回结果类
 * </p>
 * @Author Jiao Tong
 * @Date 2021/3/8 9:16
 * @Version 1.0
 */
@Data
@ApiModel(value = "R对象", description = "统一返回结果类")
public class R {

    @ApiModelProperty(value = "是否成功")
    private Boolean success;

    @ApiModelProperty(value = "返回码")
    private Integer code;

    @ApiModelProperty(value = "返回信息")
    private String message;

    @ApiModelProperty(value = "返回数据")
    private Map<String, Object> data = new HashMap<>();

    //私有构造  以免外部随意调用  此类只能通过提供的指定方法创建实例
    private R(){}

    /**
     * 成功的方法
     * @return
     */
    @ApiOperation(value = "成功的方法")
    public static R ok() {
        R r = new R();

        r.setSuccess(true);
        r.setCode(ResultCode.SUCCESS);
        r.setMessage("成功");

        return r;
    }

    /**
     * 失败的方法
     * @return
     */
    @ApiOperation(value = "失败的方法")
    public static R error() {
        R r = new R();

        r.setSuccess(false);
        r.setCode(ResultCode.ERROR);
        r.setMessage("失败");

        return r;
    }

    //返回this的作用  能够使用链式编程
    public R success(Boolean success) {
        this.setSuccess(success);
        return this;
    }

    public R code(Integer code) {
        this.setCode(code);
        return this;
    }

    public R message(String message) {
        this.setMessage(message);
        return this;
    }

    public R data(String key, Object value) {
        this.data.put(key, value);
        return this;
    }

    public R data(Map<String, Object> data) {
        this.setData(data);
        return this;
    }
    
    // 简单的链式编程使用
    public static void main(String[] args) {
        R.ok()
            .data("link", "链式编程");
    }

}

posted on 2021-03-31 15:43  jiaotong  阅读(60)  评论(0)    收藏  举报