java中的抽象类与接口(面试常考,重要)!!

2023-05-16

目录

  • 抽象类
    • 语法规则
    • 注意事项(重要,全部掌握)
    • 抽象类的作用
  • 接口
    • 语法规则
    • 注意事项
    • 提示
    • 类实现多个接口
  • 接口使用实例(Comparable 接口与Comparator接口)
    • Comparable接口
    • Comparator接口(比较器)
      • Comparable接口 与Comparator接口的区别
      • 代码示例
  • 接口间的继承(扩展)
  • 总结

抽象类

语法规则

在多态关于形状的代码例子中, 我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它设计成一个 抽象方法(abstract method), 包含抽象方法的类我们称为 抽象类(abstract class).

abstract class Shape {
            abstract public void draw();
        }
  • 在 draw 方法前加上 abstract 关键字, 表示这是一个抽象方法. 同时抽象方法没有方法体(没有 { }, 不能执行具体代码).
  • 对于包含抽象方法的类, 必须加上 abstract 关键字表示这是一个抽象类.

注意事项(重要,全部掌握)

  • 抽象方法:一个方法如果被abstract修饰,那么这个方法就是抽象方法。抽象方法可以没有具体的实现。

    同时抽象方法不能被private修饰,因为一旦被private修饰后,非抽象子类是不能重写父类私有的抽象方法的。

  • 包含抽象方法的类称作抽象类,其必须被abstract所修饰,一个抽象类中可以没有抽象方法,但是如果一个类中有抽象方法,那么这个类一定是抽象类,其必须被abstract所修饰

  • 抽象类不可以被实例化。不能使用例如Shape shape = new Shape();这样的语句
    在这里插入图片描述
    但是不影响抽象类发生向上转型,所以说抽象类不可以被实例化,但是可以发生向上转型.

  • 类内的数据成员,和普通类没有区别,可以包含其他的非抽象方法, 也可以包含字段. 这个非抽象方法和普通方法的规则都是一样的, 可以被重写,也可以被子类直接调用

  • 抽象类主要就是用来被继承的.

  • 如果一个非抽象类继承了这个抽象类,那么这个类必须重写抽象类当中的所有的抽象方法。(重要)

  • 当抽象类A 继承 抽象类B 那么A可以不重写B中的抽象方法,但是一旦A要是再被一个非抽象类c继承,那么c类中一定还要重写A中和B中的抽象方法.
    代码示例:

abstract class A {
    abstract public void eat();

    public void drink() {

    }
}

abstract class C extends A {
    abstract public void fly();
}

class b extends C {
    @Override
    public void eat() {
        System.out.println("eat");
    }

    @Override
    public void fly() {
        System.out.println("fly");
    }
}
  • 抽象类和抽象方法一定是不能被final修饰的,因为一旦类被final修饰,便不能继承,方法被final修饰,不能被重写
    抽象类不能实例化的目的也就是为了继承和重写,所以两者不能同时使用
  • 抽象类实现接口时,可以不需要对接口方法进行重写,即可以重写一部分,不重写一部分
  • 抽象类有构造方法,但是不能使用,即不能创建具体的对象

抽象类的作用

 抽象类存在的最大意义就是为了被继承.

抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.
有些同学可能会说了, 普通的类也可以被继承呀, 普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?

答:确实如此. 但是使用抽象类相当于多了一重编译器的校验.
使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成.
那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.

很多语法存在的意义都是为了 “预防出错”, 例如我们曾经用过的 final 也是类似. 创建的变量用户不去修改, 不就相当于常量嘛? 但是加上 final 能够在不小心误修改的时候, 让编译器及时提醒我们.
充分利用编译器的校验, 在实际开发中是非常有意义的.

实际开发中,抽象类的作用也是非常重要的:

抽象类可以降低接口实现类对接口实现过程难度,因为在实际开发中一个接口中可能会有很多接口是使用不到的,当一个非抽象类去继承这个接口的时候,就需要重写这个接口中的所有抽象方法,造成代码冗余,为了避免这种情况的发生,此时就需要抽象类将接口中不需要使用的抽象方法进行重写,将需要使用的抽象方法继承下来.
这样其他类只需要去继承不同的抽象类,依照自己业务的要求去寻找自己所需要的抽象类,然后对抽象类中的抽象方法进行重写就行了,从而降低了接口实现过程中的难度。

接口

接口是抽象类的更进一步. 抽象类中还可以包含非抽象方法, 和字段. 而接口中包含的方法都是抽象方法, 字段只能包含静态常量.

语法规则

我们直接通过一段代码来进行总结:

1.interface Shape1 {  
 -    //接口中定义的成员变量都会被默认为常量,由public  static final默认进行修饰,所以就算不写public  static final也无所谓,  
 -    int a = 10;  
 -    public static final String name = "sss";  
 -  
 -    //接口中的方法几乎都为抽象方法,默认为public abstract进行修饰,所以就算不写public abstract也无所谓  
 -    void draw();  
 -  
 -    //当然接口中也可以定义非抽象方法,用default关键字即可,default是在java8中引入的关键字,具体可看csdn博客  
 -    default void drink() {  
 -        System.out.println("喝水");  
 -    }  
13.}  
 -  
15.class Cycle1 implements Shape1 {  
 -    @Override  
 -    public void draw() {  
 -        System.out.println("画一个⚪");  
 -    }  
 -  
21.}  
 -  
23.class React1 implements Shape1 {  
 -    @Override//注解  
 -    public void draw() {  
 -        System.out.println("画一个□");  
 -    }  
 -  
29.}  
 -  
31.public class TestMain {  
 -    public static void fun(Shape1 shape) {  
 -        shape.draw();  
 -    }  
 -  
 -    public static void main(String[] args) {  
 -        //接口也是可以发生向上转型的,前提是一个类必须实现了这个接口  
 -        //例如下面的代码,因为Cycle1类实现了Shape1这个接口,所以此时接口类型的shape引用可以指向Cycle1类的实例了  
 -        Shape1 shape = new Cycle1();  
 -        Shape1 shape1=new React1();  
 -        shape.draw();  
 -        shape1.draw();  
 -    }  
44.}  
  • 使用 interface 定义一个接口
  • 接口中的方法一定是抽象方法, 因此可以省略 abstract
  • 接口中的方法一定是 public,因此可以省略 public
  • Cycle 使用 implements 继承接口. 此时implements表达的含义不再是 “扩展”, 而是 “实现”
  • 在调用的时候同样可以创建一个接口的引用, 对应到一个子类的实例.
  • 接口不能单独被实例化.

注意事项

  • 接口当中的方法都是抽象方法。其默认前缀为public abstract,在书写时是可以省略的,因为编译器默认这个方法就是 public abstract
  • 抽象类其实可以有具体实现的方法。这个方法是被default修饰的(JDK1.8加入的
  • 接口当中只能包含静态常量,所有常量的前缀全部默认为public static
    final,在书写时是可以省略的,因为编译器默认这个成员变量就是public static final
  • 接口当中的成员变量默认是:public static final 成员方法是:public abstract
  • 接口是不可以被实例化的。 Shape shape = new Shape();(不允许
  • 接口和类之间的关系 : implements(实现),当一个非抽象类实现了这个接口且接口中有抽象方法时,则这个类必须重写接口中的所有抽象方法,如果这个类是抽象类,则可以不实现接口中的所有方法,因为抽象类中允许有抽象方法的存在
  • 接口的出现是为了实现多继承.一个类可以实现多个接口但是只能继承一个父类
  • 只要这个类 实现了该接口,那么就可以进行向上转型
  • 当然一个接口也可以去继承(扩展)多个接口

扩展(extends)与实现(implements)的区别

扩展指的是当前已经有一定的功能了, 进一步扩充功能.
实现指的是当前啥都没有, 需要从头构造出来.

提示

1.我们创建接口的时候, 接口的命名一般以大写字母 I 开头.
2.接口的命名一般使用 “形容词” 词性的单词.
3.阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性.
不加任何修饰符号的意思就是常量省略public static final ,抽象方法省略前缀public abstract
一个错误的代码:

interface IShape {
    // 即便不写public,也是默认为public权限
    abstract void draw();
}

class Rect implements IShape {
    void draw() {
        //权限更加严格了,所以无法覆写。意思就是Rect类中重写draw方法时必须加上public才可以
        System.out.println("□");
    }
}

在这里插入图片描述

类实现多个接口

有的时候我们需要让一个类同时继承自多个父类. 这件事情在有些编程语言通过 多继承 的方式来实现的.
然而 Java 中只支持单继承, 一个类只能 extends 一个父类. 但是可以同时实现多个接口, 也能达到多继承类似的效果. 现在我们通过类来表示一组动物.

class Animal {
    protected String name;

    public Animal(String name) {
        this.name = name;
    }
}

另外我们再提供一组接口, 分别表示 “会飞的”, “会跑的”, “会游泳的”.

interface IFlying {
    void fly();
}

interface IRunning {
    void run();
}

interface ISwimming {
    void swim();
}

接下来我们创建几个具体的动物
猫, 是会跑的.

class Cat extends Animal implements IRunning {
    public Cat(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name + "正在用四条腿跑");
    }
}

鱼, 是会游的.

class Fish extends Animal implements ISwimming {
    public Fish(String name) {
        super(name);
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在用尾巴游泳");
    }
}

青蛙, 既能跑, 又能游(两栖动物)

class Frog extends Animal implements IRunning, ISwimming {
    public Frog(String name) {
        super(name);
    }

    @Override
    public void run() {
        System.out.println(this.name + "正在往前跳");
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在蹬腿游泳");
    }
}

有一种神奇的动物, 水陆空三栖, 叫做 “鸭子”

class Duck extends Animal implements IRunning, ISwimming, IFlying {
    public Duck(String name) {
        super(name);
    }

    @Override
    public void fly() {
        System.out.println(this.name + "正在用翅膀飞");

    }

    @Override
    public void run() {
        System.out.println(this.name + "正在用两条腿跑");
    }

    @Override
    public void swim() {
        System.out.println(this.name + "正在漂在水上");
    }
}

上面的代码展示了 Java 面向对象编程中最常见的用法: 一个类继承一个父类, 同时实现多种接口.
继承表达的含义是 is - a 语义, 而接口表达的含义是 具有 xxx 特性 .

猫是一种动物, 具有会跑的特性.
青蛙也是一种动物, 既能跑, 也能游泳
鸭子也是一种动物, 既能跑, 也能游, 还能飞

这样设计有什么好处呢? 时刻牢记多态的好处, 让程序猿忘记类型. 有了接口之后, 类的使用者就不必关注具体类型, 而只关注某个类是否具备某种能力.
例如, 现在实现一个方法, 叫 “散步”

public static void walk(IRunning running) {
        running.run();
}

在这个 walk 方法内部, 我们并不关注到底是哪种动物, 只要参数是会跑的,就行,此时需要注意的是这个会跑的前提是这个类必须实现了IRunning接口才可以

        //因为此时Cat类实现的是IRunning接口,所以此时可以使用向上转型如下所示,若没有实现IRunning接口,则会报错
        IRunning iRunning = new Cat("猫猫");
        walk(iRunning);

        //同样的因为此时Frog类实现的是IRunning接口,所以此时可以使用向上转型如下所示,若没有实现IRunning接口,同样会报错
        IRunning iRunning1 = new Frog("青蛙");
        walk(iRunning1);

接口使用实例(Comparable 接口与Comparator接口)

Comparable接口

刚才的关于例子比较抽象, 我们再来一个更能实际的例子.
给对象数组排序
给定一个学生类

class Student {
    private String name;
    private int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "[" + this.name + ":" + this.score + "]";
    }
}

再给定一个学生对象数组

Student[]students=new Student[]{
        new Student("张三",95),
        new Student("李四",96),
        new Student("王五",97),
        new Student("赵六",92),
        };

现对这个对象数组中的元素进行排序(按分数降序).
按照我们之前的理解, 数组我们有一个现成的 sort 方法, 能否直接使用这个方法呢?

Arrays.sort(students);
System.out.println(Arrays.toString(students));

// 运行出错, 抛出异常.
        Exception in thread"main"java.lang.ClassCastException:Student cannot be cast to java.lang.Comparable

我们呢会发现此时会发生类型转换异常,仔细思考, 不难发现, 和普通的整数不一样, 两个整数是可以直接比较的, 大小关系明确. 而两个学生对象的大小关系怎么确定? 需要我们额外指定.
假设我们不去指定的话,我们也不知道到底是按照学生姓名比较,还是学生的年龄来进行比较.
此时就需要让我们的 Student 类实现 Comparable 接口, 并重写 其中的 抽象的compareTo 方法,下面来看代码:

1.//自定义类型比较大小需要实现Comparable接口,<>为泛型  
2.//对于Comparable接口来说,一般都是在类的内部定义的
3.class Student implements Comparable<Student> {  
4.    public String name;  
5.    public int age;  
6.    public int score;  
7.  
8.    public Student(String name, int age, int score) {  
9.        this.name = name;  
10.        this.age = age;  
11.        this.score = score;  
12.    }  
13.  
14.    //重写toString方法  
15.    @Override  
16.    public String toString() {  
17.        return "Student{" +  
18.                "name='" + name + '\'' +  
19.                ", age=" + age +  
20.                ", score=" + score +  
21.                '}';  
22.    }  
23.  
24.    //因为此时实现了Compareable接口,则需要重写其内部的抽象方法compareTo  
25.    @Override  
26.    public int compareTo(Student o) {  
27.        //通过分数来进行排序,如果想通过年龄等直接修改score替换成age即可  
28.        //如果大于的时候return 1,小于return -1,说明是按照从小到大的顺序排列的
29.        //如果大于的时候return -1,小于return 1,说明是按照从大到小的顺序排列的
30.        if(this.score > o.score) {  
31.            return 1;  
32.        }else if(this.score == o.score) {  
33.            return 0;  
34.        }else {  
35.            return -1;  
36.        }  
37.    }  
38.}  
39.public class TestDemo2 {  
40.  
41.    public static void main(String[] args) {  
42.        //如果想要对Student类的引用进行大小比较,就需要Student类去实现Comparable接口  
43.        Student student1 = new Student("bit",18,79);  
44.        Student student2 = new Student("gao",29,70);  
45.        Student student3 = new Student("shasha",17,99);  
46.          
47.        Student[] students = new Student[3];  
48.        students[0] = student1;  
49.        students[1] = student2;  
50.        students[2] = student3;  
51.  
52.        //sort方法默认从小到打排序  
53.        Arrays.sort(students);  
54.        System.out.println(Arrays.toString(students));  
55.    }  
56.}

此时我们通过分数进行排序,在 sort 方法中会自动调用 compareTo 方法. compareTo 的参数是 Object , 其实传入的就是 Student 类型的对象. 然后比较当前对象和参数对象的大小关系(按分数来算).

如果当前对象应排在参数对象之前, 返回小于 0 的数字;
如果当前对象应排在参数对象之后, 返回大于 0 的数字;
如果当前对象和参数对象不分先后, 返回 0;

再次执行程序, 结果就符合预期了.

// 执行结果
[Student{name=‘gao’, age=29, score=70}, Student{name=‘bit’, age=18, score=79}, Student{name=‘shasha’, age=17, score=99}]

注意:
但是上述的比较方式是有局限性的,因为上述的比较方式中是直接把比较写死的,可以说只能比较年龄,不能比较姓名等其他东西,但是我现在就想比较除掉年龄的其他东西该怎么办?此时就用到了比较器.
对于 sort 方法来说, 需要传入的数组的每个对象都是 “可比较” 的, 需要具备 compareTo 这样的能力. 通过重写 compareTo 方法的方式, 就可以定义比较规则.

Comparator接口(比较器)

Comparable接口 与Comparator接口的区别

首先我们知道的是Compareable接口是定义在类的内部 来实现对象的比较的,而我们比较器Comparator是专门定义在类的外部的

代码示例

还是之前的学生类,不同的是Student类不再实现Compareable接口:

此时我们想根据分数来对学生进行排序,那就在类的外部重新定义一个public类去实现Comparator接口重写Comparator接口中的compare方法,以此来实现我们对于分数的比较和排序:来看代码:
首先来看Comparator接口中的compare方法:
在这里插入图片描述
来看对于分数比较的代码

//ScoreComparator.java类
public class ScoreComparator implements Comparator<Student> {
    @Override
    public int compare(Student o1, Student o2) {
        return o1.score - o2.score;
    }
}

如果还想要对于学生的名字进行比较:来看代码实现:

public class NameComparator implements Comparator<Student> {

    @Override
    public int compare(Student o1, Student o2) {

        return o1.name.compareTo(o2.name);
    }
}

这块的代码就不能再使用o1.name-o2.name这样的写法了,原因是我们的name是String类型,是不能进行相加减的,所以此处应该使用compareTo方法,有些同学可能就会纳闷了,compareTo方法出现于Compareable接口中,为什么要在这里使用这个呢?
答案如下:

我们先来看String类的源码:
在这里插入图片描述
可以看到String类实现了我们的Compareable接口,并重写了我们Compareable接口中的compareTo方法
在这里插入图片描述

所以关于名字的比较器我们可以知道它虽然实现了Comparator接口但是其内部使用的compareTo方法来源于Compareable接口.
下面来看主函数中是如何实现对于名字和分数的比较的:

class Student {
    public String name;
    public int score;

    public Student(String name, int score) {
        this.name = name;
        this.score = score;
    }

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", score=" + score +
                '}';
    }

}

public class TestDemo2 {

    public static void main(String[] args) {
        Student[] students = new Student[3];
        students[0] = new Student("bit", 89);
        students[1] = new Student("abc", 19);
        students[2] = new Student("htf", 59);
        System.out.println("===============没有排序前==============");
        System.out.println(Arrays.toString(students));
        System.out.println("===============根据分数排序后==============");
        ScoreComparator scoreComparator = new ScoreComparator();
        //传两个参数进来
        Arrays.sort(students, scoreComparator);
        //输出结果为:[Student{name='abc', score=19}, Student{name='htf', score=59}, Student{name='bit', score=89}]
        System.out.println(Arrays.toString(students));

        System.out.println("===============根据姓名进行排序后==============");
        NameComparator nameComparator = new NameComparator();
        Arrays.sort(students, nameComparator);
        //输出结果为:[Student{name='abc', score=19}, Student{name='bit', score=89}, Student{name='htf', score=59}]
        //以上姓名的排序是按照首字母进行排序的
        System.out.println(Arrays.toString(students));
    }
}

接口间的继承(扩展)

接口可以继承一个接口,也可以继承(扩展)多个接口,已达到复用的效果. 使用 extends 关键字.当然这里的继承关系我们把它理解成扩展的意思更为准确

interface IRunning { void run();
}

interface ISwimming { void swim();
}

// 两栖的动物, 既能跑, 也能游
interface IAmphibious extends IRunning, ISwimming {
  //此时IAmphibious这个接口相当于有了两个方法,一个是run,一个是swim
}

class Frog implements IAmphibious {
 //此时Frog这个类必须重写IAmphibious这个接口的两个抽象方法,一个run方法,一个swim方法
}

通过接口继承创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就继续要实现 run 方法, 也需要实现 swim 方法.

总结

抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! 常见面试题).

核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.

如之前写的 Animal 例子. 此处的 Animal 中包含一个 name 这样的属性, 这个属性在任何子类中都是存在的. 因此此处的 Animal 只能作为一个抽象类, 而不应该成为一个接口.

        class Animal {
            protected String name;
            public Animal(String name) {
                this.name = name;
            }
        }

再次提醒:

抽象类存在的意义是为了让编译器更好的校验, 像 Animal 这样的类我们并不会直接使用, 而是使用它的子类. 万一不小心创建了Animal 的实例, 编译器会及时提醒我们.

在这里插入图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

java中的抽象类与接口(面试常考,重要)!! 的相关文章

  • 如何查看Pocketsphinx词典中是否存在该单词?

    我只是想看看字典文件中是否存在字符串 字典文件位于问题底部 我想检查语音识别器是否可以识别单词 例如 识别器将无法识别字符串ahdfojakdlfafiop 因为字典中没有定义 所以 我可以检查某个单词是否在 pocktsphinx 词典中
  • 是否可以在 Spring Batch 中结合分区和并行步骤?

    我只是想知道它在 Spring Batch 中可行吗 Step1Step2 流程 gt 流程1 流程2 流程3 Step3 其中每个flow1 gt 划分为 5 个 GridSizeflow2 gt 划分为 5 个 GridSizeflow
  • java.lang.Class: 在 java 程序中初始化 log4j 属性文件时出错

    我正在尝试使用 log4j 运行独立的 java 程序 但在调试时收到以下消息 控制台上没有 log4j 相关日志 log Logger 1343 java lang Class ERROR in 18b4aac2 有人可以建议这里出了什么
  • 无法加载 jar 文件的主类

    我使用 Eclipse IDE 开发了一个应用程序 创建应用程序后 我以 jar 格式导出项目 当我尝试运行此 jar 文件时 出现错误 无法加载主类 请帮忙 当您将项目导出为 jar 时 请参阅此所以问题 https stackoverf
  • 如何对 IntStream 进行逆序排序

    我正在使用 txt 文件读取数字BufferedReader 我想颠倒该流中元素的顺序 以便在收集它们时 它们将从最高到最低排列 我不想在构建数组后进行排序 因为我不知道其中可能有多少元素 我只需要最高的 N 个元素 in new Buff
  • Java 泛型/类型调度问题

    考虑以下程序 import java util List import java util ArrayList public class TypeTest public static class TypeTestA extends Type
  • PropertySources 中各种源的优先级

    Spring引入了新的注释 PropertySources对于所有标记为的类 Configuration since 4 0 需要不同的 PropertySource作为论证 PropertySources PropertySource c
  • Spring Stomp over Websocket:流式传输大文件

    我的SockJs客户端在网页中 发送帧大小为16K的消息 消息大小限制决定了我可以传输的文件的最大大小 以下是我在文档中找到的内容 Configure the maximum size for an incoming sub protoco
  • 如何将 XMP XML 块序列化为现有的 JPEG 图像?

    我有许多 JPEG 图像 其中包含损坏的 XMP XML 块 我可以轻松修复这些块 但我不确定如何将 固定 数据写回图像文件 我目前正在使用 JAVA 但我愿意接受任何能让这项任务变得容易的事情 这是目标关于 XMP XML 的另一个问题
  • 所有junit测试后的清理

    在我的项目中 我必须在所有测试之前进行一些存储库设置 这是使用一些棘手的静态规则来完成的 然而 在所有测试之后我不知道如何进行清理 我不想保留一些神奇的静态数字来引用所有测试方法的数量 我应该一直维护它 最受赞赏的方法是添加一些侦听器 该侦
  • 使用 java 按电子邮件发送日历邀请

    我正在尝试使用 java 发送每封电子邮件的日历邀请 收件人收到电子邮件 但不会显示接受或拒绝的邀请 而是将该事件自动添加到他的日历中 我正在使用 ical4j jar 构建活动 邀请 private Calendar getInvite
  • Install4j:如何在安装结束时执行命令行 java -jar filename.jar

    在 Intall4j 中 在安装结束时 我只想通过执行如下命令行来初始化某些内容 java jar filename jar 我怎样才能归档这个任务install4j Thanks 将 运行可执行文件或批处理文件 操作添加到 安装屏幕 并设
  • 参数动态时如何构建 JPQL 查询?

    我想知道是否有一个好的解决方案来构建基于过滤器的 JPQL 查询 我的查询太 富有表现力 我无法使用 Criteria 就像是 query Select from Ent if parameter null query WHERE fiel
  • 在 AKKA 中,对主管调用 shutdown 是否会停止其监督的所有参与者?

    假设我有一位主管连接了 2 位演员 当我的应用程序关闭时 我想优雅地关闭这些参与者 调用supervisor shutdown 是否会停止所有参与者 还是我仍然需要手动停止我的参与者 gracias 阻止主管 https github co
  • 阻止 OSX 变音符号为所有用户禁用 Java 中的 KeyBindings?

    注 我知道这个问题 https stackoverflow com questions 40335285 java keybinds stop working after holding down a key用户必须输入终端命令才能解决此问
  • 从一个文本文件中获取数据并将其移动到新的文本文件

    我有一个文件 里面有数据 在我的主要方法中 我读入文件并关闭文件 我调用另一种方法 在原始文件的同一文件夹内创建一个新文件 所以现在我有两个文件 原始文件和通过我调用的方法生成的文件 我需要另一种方法 从原始文件中获取数据并将其写入创建的新
  • Spring Boot MSSQL Kerberos 身份验证

    目前在我的春季靴子中application properties文件中 我指定以下行来连接到 MSSql 服务器 spring datasource url jdbc sqlserver localhost databaseName spr
  • Java中有类似分支/跳转表的东西吗?

    Java有类似分支表或跳转表的东西吗 分支表或跳转表是 根据维基百科 http en wikipedia org wiki Branch table 用于描述使用分支指令表将程序控制 分支 转移到程序的另一部分 或可能已动态加载的不同程序
  • Java 推断泛型类型

    我正在寻找类似的推断捕获泛型类型的概念 类似于以下方法片段 但不是捕获泛型类型的类 public
  • 尝试使用带有有效购买令牌的 Java Google Play Developer API v3 检索应用内购买信息时出现错误请求(无效值)

    当使用 Java Google Play Developer API 版本 3 并请求有效购买令牌的购买信息时 我收到以下异常 API 调用返回 400 Bad Request 响应以及以下消息 code 400 errors domain

随机推荐

  • DELL R730服务器安装centos7.3教程

    服务器安装centos7 3系统分为两步 第一步 xff0c 对磁盘进行分组并部署raid 第二步 xff0c 通过系统安装程序安装操作系统 xff0c 并进行系统安装配置 第一步 xff0c RADI的分组部署 将服务器开机 xff0c
  • 访问控制ACL

    ACL访问控制列表可以对具体的用户或组设置权限 root 64 localhost useradd tony tom root 64 localhost passwd tony root 64 localhost passwd tom ro
  • NFS与自动挂载

    1 NFS共享文件server端的配置 xff08 server ip xff1a 172 16 8 11 xff09 root 64 localhost getenforce Enforcing root 64 localhost set
  • SAP主题改变方法

    背景 xff1a SAP7 6有很多主题 xff0c 然后按以下的方法可以改变 xff08 我比较习惯blue这个主题目 xff0c 7 6版本现在默认不是这个主题目 xff09 文章目录 方法一 通过登录后设置步骤1步骤2 方法二 通过程
  • SMB文件共享

    1 windows server端配置 C Users wll gt net share 共享名 资源 注解 C C 默认共享 D D 默认共享 IPC
  • swap空间扩容

    1 查看现有swap空间大小 root 64 centos7 free total used free shared buff cache available Mem 2028116 389108 1266584 12644 372424
  • Linux 卸载及删除磁盘分区

    1 卸载分区 root 64 centos7 df Th Filesystem Type Size Used Avail Use Mounted on dev mapper centos root xfs 17G 4 0G 14G 24 d
  • 磁盘阵列raid5的创建及管理

    1 在虚拟机上添加4个磁盘 xff0c 其中主用盘3个 xff0c 热备盘1个 root 64 centos7 fdisk l Disk dev sda 21 5 GB 21474836480 bytes 41943040 sectors
  • Keil关于.axf文件报错

    项目场景 xff1a 熟悉Keil C51的同学在使用Keil MDK编译STM32系列单片机时会更容易上手 Keil C51是美国Keil Software公司出品的51系列兼容单片机C语言软件开发系统 xff0c 与汇编相比 xff0c
  • 《java核心技术卷1》部分章节读书笔记

    目录 3 java基本的程序设计结构3 1 命名规范3 2 数据类型3 3 运算符3 4 枚举类型 3 5 字符串3 6 大数值 BigInteger和BigDecimal3 7 数组 4 对象与类4 1 识别类4 2 类之间的关系4 3
  • linux 问题-——退出vi编辑器 wq失效

    退出linux的vi编辑器时 xff0c 先按左上角的esc按键 xff0c 再输出输入命令 保存不退出w强制保存但不退出w 保存并退出wq强制保存并退出wq xff01 不保存退出q不保存并强制退出q 出现以下问题 xff1a esc退出
  • SUMO中车辆类型的定义及路由文件的写法

    车辆类型的定义 在SUMO中 xff0c 通过vType标签来定义车辆的类型 xff0c 一般可以写成如下形式 xff1a span class token operator lt span vType id span class toke
  • 为什么c语言允许直接访问物理地址?

    C语言允许直接访问物理地址 xff0c 是因为它是一种面向底层的语言 xff0c 提供了底层的硬件操作和系统调用的能力 在C语言中 xff0c 可以通过指针变量直接访问内存地址 xff0c 从而对硬件进行底层控制和操作 在一些应用场景下 x
  • TortoiseGit 安装和使用

    TortoiseGit是一款适用于Windows系统的开源的git版本控制客户端 xff0c 其优点是使用图像化界面操作 xff0c 而不需要记住或使用Git命令 xff0c 从而增加开发效率 xff0c 对不熟悉命令的使用者比较友善 下面
  • 解放拖动屏幕的双手——用xrandr配置多屏显示

    操作系统 xff1a Arch Linux 桌面系统 xff1a Xfce 又是一次会议的结束 xff0c 待我回办公室把大屏幕接上 xff0c 准备继续干 等等 xff0c 这是怎么回事 xff1f 打开系统的Display设置一看 xf
  • 深入浅出BGP

    文章目录 深入浅出BGP说明一 BGP的产生1 1 动态路由的分类1 2 BGP概述 二 与IGP的区别三 BGP核心3 1 属性3 1 1 属性特点 3 2 选路规则3 3 对等体 深入浅出BGP 说明 此篇主要对BGP的产生 与IGP的
  • LVM跨主机迁移

    LVM跨主机迁移 虚拟机 实验环境 两台Centos 7 8虚拟机 xff0c IP xff1a 192 168 221 199 200 查看lv test中的数据 使用命令lsblk xff0c 确认逻辑卷vg下挂有两个分区均为sdb磁盘
  • CodeBlocks 20.03安装&汉语化&找不到编译器

    一 CodeBlocks下载 下载地址 xff1a https www codeblocks org downloads binaries 到如下界面选择下载codeblocks 20 03mingw setup exe xff0c 这个里
  • 【FreeRTOS】从0写简易RTOS实现任务切换

    1 RTOS引入 单片机性能越来越强 xff0c 很多Linux程序在单片机上也可以运行了 xff1a 这需要RTOS 我们要开发的单片机产品 xff0c 功能也越来越丰富 xff1a 这也需要RTOS 就个人技术发展来说 xff0c 单片
  • java中的抽象类与接口(面试常考,重要)!!

    目录 抽象类语法规则注意事项 重要 xff0c 全部掌握 抽象类的作用 接口语法规则注意事项提示类实现多个接口 接口使用实例 Comparable 接口与Comparator接口 xff09 Comparable接口Comparator接口