精华内容
下载资源
问答
  • 第1条 考虑用静态方法代替构造器类可以通过静态工厂方法来提供它的客户端,而不是通过构造器。提供静态工厂方法而不是公有构造器,这样做具有大优势。1.静态工厂方法与构造器不同的第大优势在于,它们名称。...
    97c354aad6e7517e75725135c56ac4dd.png

    第1条 考虑用静态方法代替构造器

    类可以通过静态工厂方法来提供它的客户端,而不是通过构造器。提供静态工厂方法而不是公有构造器,这样做具有几大优势。

    1.静态工厂方法与构造器不同的第一大优势在于,它们有名称。

    例如,构造器BigInteger(int,int,Random)返回的BigInteger可能为素数,如果名为BigInteger.probablePrime的静态工厂方法来表示,显然更为清晰

    2.静态工厂方法与构造器不同的第二大优势在于,不用在每次调用它们的时候都创建一个新对象。

    静态工厂方法能够为重复的调用返回相同对象,这样有助于类总能控制在某个时刻哪些实例应该存在。这种类被称作实例受控的类。实例受控使得类可以确保他是一个Singleton或者是不可实例化的。

    3.静态工厂方法与构造器不同的第三大优势在于,它们可以返回原返回类型的任何子类型的对象。

    这种灵活性的一种应用是,API可以返回对象,同时又不会使对象的类变成公有的。以这种方式隐藏实现类会使API变的非常简洁。

    4.静态工厂方法的第四大优势在于,在创建参数化类型实例的时候,它们使代码变得更加简洁

    其实这一点java1.7就已经优化,调用参数化构造器时,它会自动进行类型检查,不需要显示申明

    Map> map = new HashMap>();

    //上下两种方式都是可以的

    Map> map = new HashMap<>();

    静态工厂方法的主要缺点在于,类如果不含公有的或者受保护的构造器,就不能被子类化。

    静态工厂方法的第二个缺点在于,它们与其他的静态方法实际上没有任何区别。

    最后附上静态工厂方法的一些惯用命名:

    valueOf----不太严格讲,该方法返回的实例与它的参数具有相同的值。这样的静态工厂方法实际上是类型转换方法。

    of----valueOf的一种更为简洁的替代,在EnumSet中使用并流行起来。

    getInstance----返回的实例是通过方法的参数来描述的。

    newInstance----和getInstance一样,但newInstance能够确保返回的每个实例都与所有其他实例不同。

    getType----和getInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。

    newType----和newInstance一样,但是在工厂方法处于不同的类中的时候使用。Type表示工厂方法所返回的对象类型。

    23be00420ee0eadac754162983817fde.png

    第2条 遇到多个构造器参数时要考虑用构建器

    静态工厂和构造器有个共同的局限性:它们都不能很好地扩展到大量的可选参数。

    第三种替代方法,即能保证像重叠构造器模式那样的安全性,也能保证像JavaBeans模式那么好的可读性。这就是Builder模式的一种形式。不直接生成想要的对象,而是让客户端利用所有必要的参数调用构造器(或者静态工厂),得到一个builder对象。让后客户端在builder对象上调用类似于setter的方法,来设置每个相关的可选参数。最后客户端调用无参的builder方法来生成不可变的对象。

    其实,像SpringBoot启动类就是个典型的例子:

    public class Application extends SpringBootServletInitializer {

    public static void main(String[] args) throws Exception {

    //使用构建器创建SpringApplication对象

    SpringApplication springApplication = new SpringApplicationBuilder()

    .bannerMode(Banner.Mode.CONSOLE)

    .initializers(ApplicationContextInitializerImpl.instance())

    .sources(Application.class)

    .build();

    springApplication.run();

    }

    }

    第3条 用私有构造器或者枚举类型强化Singleton属性

    实现Singleton有两种方法。这两种方法都要把构造器保持为私有的,并导出公有的静态成员,以便允许客户端能够访问该类的唯一实例。

    实现Singleton还有第三种方法。只编写一个包含单个元素的枚举类型:

    private enum Elvis {

    INSTANCE;

    public void leaveTheBuilding(){...}

    }

    第4条 通过私有构造器强化不可实例化的能力

    其实就像一些工具类,我们不想让其他用户创建该类对象,也不想被其他类继承,我们只要把这个类的构造器私有化,他就不能被实例化了。

    第5条 避免创建不必要的对象

    一般来说,最好能重用对象而不是在每次需要的时候就创建一个相同功能的新对象。

    对于同时提供了静态工厂方法和构造器的不可变类,通常可以使用静态工厂方法而不是构造器,以避免创建不必要的对象。因为构造器在每次被调用的时候都会创建一个新的对象,而静态工厂方法只会创建一个。

    要优先使用基本类型而不是装箱基本类型,要当心无意识的自动装箱。

    当你应该重用现有对象的时候,请不要创建新的对象。

    第6条 消除过期的对象引用

    清空过期引用的另一个好处是,如果它们以后又被错误地解除引用,程序就会立即抛出空指针异常,而不是悄悄地错误运行下去。尽快地检测出程序中的错误总是有益的。

    一般而言,只要类是自己管理内存,程序员就应该警惕内存泄漏问题。一旦元素被释放掉,则该元素中包含的任何对象引用都应该被清空。

    内存泄漏的另一个常见来源是缓存。

    内存泄漏的第三个常见来源是监听器和其他回调。确保回调立即被当做垃圾回收的最佳方法是只保存它们的弱引用。

    第7条 避免使用终结方法

    终结方法通常是不可预测的,也是很危险的,一般情况下是不必要的。使用终结方法会导致行为不稳定,降低性能,以及可移植性问题。

    显示终止方法的典型例子是InputStream、OutputStream和java.sql.Connection上的close方法。显示的终止方法通常与try-finally结构结合起来使用,以确保及时终止。在finally子句内部调用显示的终止方法,可以保证即使在使用对象的时候有异常抛出,该终止方法也会执行。

    你应该在一个try块中终结子类,并在相应的finally块中调用超类的终结方法。这样做可以保证:即使子类的终结过程抛出遗产,超类的终结方法也会得到执行。

    072016f48822596f1f77d5676848c359.png
    展开全文
  • 这个问题我想了一个晚上,看了好篇别人的博客,但结果都各不相同,每个人每个人的理解,后来我想明白了:抽象类不能直接通过new去实例化一个对象,那它就是不能实例化,要获取抽象类的对象, 需要先用一个类继承...

    抽象类能实例化吗?

    这个问题我想了一个晚上,看了好几篇别人的博客,但结果都各不相同,每个人有每个人的理解,后来我想明白了:

    抽象类不能直接通过new去实例化一个对象,那它就是不能实例化,要获取抽象类的对象, 需要先用一个类继承抽象类,  然后去实例化子类。也可以用匿名内部类,在抽象类中创建一个匿名的子类,继承抽象类,通过特殊的语法实例化子类的对象 。(后面会细说)

    现在重点来了,要研究这个问题,前提是你要了解抽象类,万变不离其宗,我们从抽象类的根源谈起 , 深化对抽象类的理解。

    首先看这个例子:

    package com.my.animal;//动物类

    public classAnimal {

    String name;//名字

    String color;//颜色

    publicAnimal(String name,String color){this.name =name;this.color =color;

    }public voidrun(){

    System.out.println(name+"四条腿跑的很快!!!");

    }

    }//狗类继承动物类

    classDog extends Animal{publicDog(String name,String color){

    super(name,color);

    }

    }//鱼类继承动物类

    classFish extends Animal{publicFish(String name, String color) {

    super(name, color);

    }

    }classTest{public static voidmain(String[] args) {

    Dog dog= new Dog("哈巴狗","白色");

    dog.run();

    Fish fish= new Fish("锦鲤","红色");

    fish.run();

    }

    }

    运行结果:

    哈巴狗四条腿跑的很快!!!

    锦鲤四条腿跑的很快!!!

    是不是发现问题了,鱼怎么能用腿跑呢,难道是原始鱼?哈哈,开玩笑的,这个问题如何解决,估计大家马上想到了,在子类中重写父类的run方法不就行了,对,确实这样就可以解决,但是大家想过没有,我们是如何发现这个问题的?是不是编译运行之后才看到的,当然,也有大佬能不编译运行就能看到,不抬杠啊,意思是说有发现不了这个问题的风险,对别人可能无所谓,但对我们程序员来说,这种低级错误还是不犯的好,程序员应该有更高的追求,岂能在这被绊倒,我们要把这种风险降为零,那该如何做呢?不急,心急吃不了热豆腐,且看我慢慢分析:

    目前存在的问题:

    1.动物类的run方法描述的不正确

    2.没有强制要子类一定要重写父类的run方法

    解决方案:(抽象类的应用场景)

    我们在描述一类事物的时候,发现该种事物确实存在着某种行为,但是这种行为目前是不具体的,那么我们可以抽取这种行为的声明,但是不去实现该种行为,这时候这种行为我们称作为抽象的行为,我们就需要使用抽象类

    先看下面的例子:

    package com.my.animal;//动物类(抽象类)

    public abstract classAnimal {

    String name;//名字

    String color;//颜色//构造方法

    publicAnimal(String name,String color){this.name =name;this.color =color;

    }

    //非抽象方法

    public void eat(){

    System.out.println(name+"吃东西!!!");

    }//抽象方法

    public abstract voidrun();

    }classDog extends Animal{publicDog(String name,String color){

    super(name,color);

    }

    @Overridepublic voidrun() {

    System.out.println(name+"四条腿跑得快!!");

    }

    }classFish extends Animal{publicFish(String name, String color) {

    super(name, color);

    }

    @Overridepublic voidrun() {

    System.out.println(name+"摇摇尾巴游啊游!!");

    }

    }classTest{public static voidmain(String[] args) {

    Dog dog= new Dog("哈巴狗","白色");

    dog.run();

    Fish fish= new Fish("锦鲤","红色");

    fish.run();

    }

    }

    运行结果:

    哈巴狗四条腿跑得快!!

    锦鲤摇摇尾巴游啊游!!

    这个问题解决了,那还有一个问题就是:抽象类能实例化对象吗?

    看这个例子就知道了:

    public abstract classAnimal {

    String name;

    String color;publicAnimal(String name,String color){this.name =name;this.color =color;

    }public abstract voidrun();

    }classTest{public static voidmain(String[] args) {

    Animal a= newAnimal();

    a.run();

    }

    }

    运行结果:

    Error:(45, 20) java: com.my.animal.Animal是抽象的; 无法实例化

    抽象类注意的细节:

    1.如果一个函数没有方法体,那么该函数必须要使用abstract修饰,把该函数修饰成抽象的函数。

    2.如果一个类出现了抽象的函数,那么该类也必须使用abstract修饰。

    3.如果一个非抽象类继承了抽象类,那么必须要把抽象类的所有抽象方法全部实现。

    4.抽象类可以存在抽象方法,也可以存在非抽象方法,还可以不存在抽象方法,但是这样没任何意义,Java是不写废话的。

    5.抽象类是不能实例化对象的

    6.抽象类是存在构造函数的,其构造函数是提供给子类创建对象的时候初始化父类的属性的。

    疑问:为什么抽象类不能实例化对象?

    因为抽象类是存在抽象方法的,如果能让抽象类创建对象的话,那么使用抽象类的对象调用抽象方法是没有任何意义的。

    疑问排解了,故事结束了?不,学海本无底,我们来点扩展,就是开头提到的如何用匿名内部类去实例化子类对象。

    看下面的例子:

    package Practice_Anything;public abstract classJava_Abstract2 {public voida(){

    System.out.println("我是抽象类中的一个非抽象方法");

    }public staticJava_Abstract2 newIntences(){return newJava_Abstract2(){

    };

    }

    }classTest2{public static voidmain(String[] args) {

    Java_Abstract2 java_abstract2=Java_Abstract2.newIntences();

    java_abstract2.a();

    }

    }

    运行结果:

    我是抽象类中的一个非抽象方法

    这个故事到这就结束了,但是学习还没有停止,比如接口也是一种抽象类型,是抽象方法的集合,由此,我们是不是该联想到学习接口了呢?哈哈,学海本无底,前行莫彷徨!

    此篇为本人原创,花了大概半天时间,找了不知多少相关资料整合而成,如若对你有用,记得推荐,如若哪有不当,感谢指正!

    本文已独家授权给脚本之家(jb51net)公众号独家发布

    展开全文
  • java里初始化一个类对象,通过初始快或者构造方法进行数据赋值。与其相关的执行代码这么种: 静态初始块 初始块 构造方法 静态初始块 静态初始块只在类加载时执行一次,同时静态初始块...

    java里初始化一个类的对象,通过初始化快或者构造方法进行数据赋值。与其相关的执行代码有这么几种:

    • 静态初始化块
    • 初始化块
    • 构造方法

    静态初始化块

    静态初始化块只在类加载时执行一次,同时静态初始化块只能给静态变量赋值,不能初始化普通的成员变量。


    非静态初始化块

    非静态初始化块在每次初始化实例对象的时候都执行一次,可以给任意变量赋值。


    构造方法

    在每次初始化实例对象时调用。


    重点:执行顺序->

    1. 在加载类时执行一次静态初始化块(之后不再调用)。
    2. 在每次初始化实例对象时:先执行非静态初始化块,再执行构造方法。

    若是概念不好懂,请看如下实例:

    package com.mgh;
    
    public class Main {
    
        String name; // 声明变量name
        String sex; // 声明变量sex
        static int age;// 声明静态变量age
    
        // 构造方法
        public Main() {
            System.out.println("通过构造方法初始化name");
            name = "tom";
        }
    
        // 初始化块
        {
            System.out.println("通过初始化块初始化sex");
            sex = "男";
        }
    
        // 静态初始化块
        static {
            System.out.println("通过静态初始化块初始化age");
            age = 20;
        }
    
        public void show() {
            System.out.println("姓名:" + name + ",性别:" + sex + ",年龄:" + age);
        }
    
        public static void main(String[] args) {
    
            // 创建对象
            Main obj1 = new Main();
            Main obj2 = new Main();
            // 调用对象的show方法
            obj1.show();
            obj2.show();
        }
    }
    
    output:
    通过静态初始化块初始化age
    通过初始化块初始化sex
    通过构造方法初始化name
    通过初始化块初始化sex
    通过构造方法初始化name
    姓名:tom,性别:男,年龄:20
    姓名:tom,性别:男,年龄:20
    from https://www.cnblogs.com/Berryxiong/p/6245100.html

    转载于:https://www.cnblogs.com/shizhijie/p/8819029.html

    展开全文
  • 实例化了两坐标对象 然后放到Line里作为 private 成员变量了———————————————————————— 下面是我自己敲的代码 总共5文件 首先是包含main函数的cpp文件#i

    在慕课网学习类的封装
    看着视频跟着老师敲代码感觉很简单
    关掉视频自己敲
    敲到一半发现敲不动;
    然后又反复的看了几遍视频
    最后知道了自己不会的原因
    这里写图片描述
    这是要求
    其实老师是
    实例化了两个坐标类的对象
    然后放到Line类里作为 private 成员变量了

    ————————————————————————
    下面是我自己敲的代码
    总共有5个文件
    首先是包含main函数的cpp文件

    #include "stdafx.h"
    #include<iostream>
    #include<cstdlib>
    #include"Line.h"
    using namespace std;
    
    
    int main()
    {
         Line *p = new Line;
         delete p;
    
        return 0;
    }

    其次是Line.h文件

    #pragma once
    #include"stdafx.h"
    #include"dian.h"
    
    class Line
    {
    public:
        Line();
        ~Line();
    
        void setA(int x, int y);
        void setB(int x, int y);
    
        void printInfo();
    
    
    private:
        dian A;      //类A的对象可以成为类B的数据成员
        dian B;
    };

    然后是line.cpp文件

    #include"stdafx.h"
    #include<iostream>
    #include"Line.h"
    using namespace std;
    
    Line::Line()
    {
        cout << "Line的构造函数被执行了" << endl;
    }
    Line::~Line()
    {
        cout << "Line的析构函数被执行了" << endl;
    }
    
    void Line::setA(int x, int y)
    {
        A.setX(x);
        A.setY(y);
    }
    void Line::setB(int x, int y)
    {
        B.setX(x);
        B.setY(y);
    
    }
    
    void Line::printInfo()
    {
        cout << "点A的坐标是:" << "(" <<A.getX() << "," << A.getY() << ")" << endl;
        cout << "点B的坐标是:" << "(" << B.getX() << "," << B.getY() << ")" << endl;
    }
    

    dian.h文件

    #pragma once
    #include"stdafx.h"
    
    class dian
    {
    public:
        dian();
        ~dian();
    
        void setX( int x);
        void setY( int y);
    
        int getX();
        int getY();
    
    
    private:
        int m_X;      //表示任意一个点的X坐标
        int m_Y;
    };
    
    

    dian.cpp文件

    #include"stdafx.h"
    #include<iostream>
    #include"dian.h"
    using namespace std;
    
    dian::dian() 
    {
        cout << "点的构造函数被执行了" << endl; 
    }
    dian::~dian()
    {
        cout << "点的析构函数被执行了" << endl;
    }
        void dian :: setX(int x)
        {
            m_X = x;
        }
        void dian::setY(int y)
        {
            m_Y = y;
        }
    
        int dian::getX()
        {
            return m_X;
        }
        int dian::getY()
        {
            return m_Y;
        }
    
    
    

    **

    实例化对象A时 ,如果对象A有对象成员B,那么先执行对象B的构造函数,在执行A的构造函数

    **

    展开全文
  • 今天无意中看到一个问题:为什么抽象不能实例化?很多人的答案都是再说使用抽象的好处,但是并没有回答为什么不能实例化?这个过程就像是在回答:为什么公鸡不能下蛋?然后回答是使用公鸡可以打鸣。按照我的理解...
  • 初始 实例初始

    2020-02-28 21:39:10
    所谓实例就是加载某一个类实例化对象,这个时候才去加载成员变量(即非静态变量)和非静态代码块,以及对应的构造器(最后),这里强调对应是因为构造器可以重载,创建几个对象就实例初始化几次 父类Father.class ...
  • 抽象实例化

    2019-04-03 12:50:00
    抽象类不能直接通过new去实例化一个对象,那它就是不能实例化,要获取抽象类的对象, 需要先用一个类继承抽象类, 然后去实例化子类。也可以用匿名内部类,在抽象类中创建一个匿名的子类,继承抽象类,通过特殊的...
  • 的初始化和实例化

    2019-07-02 18:03:10
    2.在实例化的时候非静态的成员和代码块顺序执行 父类先执行父类的 可以执行好多次 创建几个对象执行几次 3.注意多态 每个变量都个this关键字修饰,指代当前对象或正在创建的对象,若子类重写了父类方法,当调用...
  • 如何实例化泛型对象

    2019-11-12 16:52:08
    jdk1.7之后所提供的ParameterizedType可以实现 getGenericSuperclass():...getActualTypeArguments():得到的是一个存放泛型的数组,用第几个就取第几个。 private static<V> void query(MyClass<V&...
  • Java中类实例化种方式

    千次阅读 2012-02-21 14:04:34
    实例化一个类一共四种途径: 1. 使用new操作符 2. 调用Class或java.lang.reflect.Constructor对象的newInstance()方法 3. 调用任何对象的clone()方法 4. 通过java.io.ObjectInputStream类的getObject() ...
  • SPRING.NET 1.3.2 学习4 --实例化对象

    千次阅读 2013-02-28 13:48:27
    在Spring.NET下实例化对象有几种方法1.使用构造器object id="exampleObject" type="Examples.ExampleObject, ExamplesLibrary"/> Examples.ExampleObject为编译成ExamplesLibrary程序集中的,ExampleObject定义在...
  • 抽象为什么不能被实例化

    千次阅读 2019-12-04 21:54:39
    今天无意中看到一个问题:为什么抽象不能实例化? 很多人的答案都是再说使用抽象的好处,但是并没有回答为什么不能实例化?这个过程就像是在回答:为什么公鸡不能下蛋?然后回答是使用公鸡可以打鸣。 按照我的...
  • 大厂面试都爱问的—对象实例化、内存布局 ...1️⃣一个类没有对外声明构造器,但是我们可以通过类对外声明的静态方法来获取一个这个类的实例. 2️⃣ 通过xxxFactory 工厂类来获取对应的类的实例. ②
  • 想要在UE4中使用代码生成角色,比如一个立方体什么的。可以在GameMode的结造函数中初始化GameMode...同样的UObject一些模板方法来实例化对象。On this page:SpawnActor 方法应用生成函数的模板生成T实例, 返
  • 1、abstract修饰类,会使这个类成为一个抽象类,这个类将不能生成对象实例,但可以做为对象变量声明的类型,也就是编译时类型,抽象类就像当于一类的半成品,需要子类继承并覆盖其中的抽象方法。2、abstract修饰方法...
  • 反过来,如果一个类可以有几个实例共存,就不要使用单例模式。 本质 控制实例数目 优点 在单例模式中,活动的单例只有一个实例,对单例类的所有实例化得到的都是相同的一个实例。这样就防止其它对象对自己的实例...
  • 今天无意中看到一个问题:为什么抽象不能实例化?很多人的答案都是再说使用抽象的好处,但是并没有回答为什么不能实例化?这个过程就像是在回答:为什么公鸡不能下蛋?然后回答是使用公鸡可以打鸣。按照我的理解...
  • 如题,我自己创建了一个HelloServlet 继承自Servlet,当请求来的时候,这个HelloServlet会被实例化, 以下问题,诚挚的向各位大佬提问,大佬也可以挑选其中某部分作答,感激不尽 问题: ①既然被实例...
  • 抽象类不能直接通过new去实例化一个对象,那它就是不能实例化,要获取抽象类的对象, 需要先用一个类继承抽象类, 然后去实例化子类。也可以用匿名内部类,在抽象类中创建一个匿名的子类,继承抽象类,通过特殊的...
  • 就像隐式类型转换一样,而对于父子类对象之间的赋值兼容是严格规定的,只有在以下种情况下才能赋值兼容:① 派生对象可以赋值给基类对象。② 派生对象可以初始基类的引用。③ 派生类对象的地址可以赋...
  • 经过系列的分析之后可以发现虽然获得了Class实例化对象,但是依然觉得这个对象获取的意义不是很大,所以为了进一步帮助大家理解反射的核心意义所以,下面将通过几个案例进行程序的说明(都是在实际开发中一定...
  • 我相信,只要每天积累一点,总一天,我也可以成为PHP编程的达人! ...首先,需要明确的就是,对象是类的实例化。 比如,student 就是一个类的名称, ...要实例化对象,首先要声明一个类。 类是由属性和方法组成的
  • 本文会记录一些本人想记录的几个关于的知识点 ...实例对象可以有多个,但是类对象只有一个。 class A(): #执行完A()内的代码,类对象A就创建了 pass B = A() #创建实例对象B C = A() #创建实例对象C D =
  • 一.java抽象类 抽象类针对的是类.包含抽象方法的类称为抽象类,但抽象类中可以没有抽象方法,它和...如果一个类继承于一个抽象类,则子类必须实现父类的抽象方法。如果子类没有实现父类的抽象方法,则子类也必须为ab
  • java对象

    2021-02-24 15:45:01
    例如在生活中,可以将人看成一个类,这个类称为人类。 对象对象是实际存在的,从属于某个类的一个个实体,因而也称为实例。简而言之,对象的抽象是类,类的具体就是对象。类用来描述一系列对象,类会概述每个...
  • 创建一个对象可以说是 创建一个实例,或者实例化一个对象,或者把类实例化 这里说的都是创建一个实实在在的食物 种说法。 是相同属性特征,行为特征,这一群体,我们定义为 用来定义的 用来创建对象...
  • (1)一个类要创建实例需要先加载并初始该类 (2)一个类要初始需先初始父类 (3)一个类初始就是执行()方法,该方法由静态类变量显示赋值代码和静态代码快组成,只执行一次,按顺序执行 2.实例初始过程 ...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 756
精华内容 302
关键字:

一个类可以有几个实例化对象