首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >这是用Kotlin在类中实例化对象的好方法吗?

这是用Kotlin在类中实例化对象的好方法吗?
EN

Stack Overflow用户
提问于 2019-10-27 19:14:24
回答 5查看 1.2K关注 0票数 3

我总是在CameraX项目中找到代码,就像代码A一样。它使用类内的companion object中的对象创建实例。

如果我写同样的代码,我将使用代码B。

用Kotlin实例化类中的对象是一种很好的方法吗?A代码比B代码好吗?

顺便说一下,我不认为“每个片段类都必须有一个空的构造函数”。请考虑一个普通的类而不是片段类,好吗?

码A

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UIFragmentPhoto internal constructor() : Fragment() {

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?) = ImageView(context)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val args = arguments ?: return
        val resource = args.getString(FILE_NAME_KEY)?.let { File(it) } ?: R.drawable.ic_photo
        Glide.with(view).load(resource).into(view as ImageView)
    }

    companion object {
        private const val FILE_NAME_KEY = "file_name"

        fun create(image: File) = UIFragmentPhoto().apply {
            arguments = Bundle().apply {
                putString(FILE_NAME_KEY, image.absolutePath)
            }
        }
    }
}

调用A

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
override fun getItem(position: Int): Fragment = UIFragmentPhoto.create(mediaList[position])

码B(修改)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UIFragmentPhoto internal constructor() : Fragment() {
    val FILE_NAME_KEY = "file_name"

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?) = ImageView(context)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val args = arguments ?: return
        val resource = args.getString(FILE_NAME_KEY)?.let { File(it) } ?: R.drawable.ic_photo
        Glide.with(view).load(resource).into(view as ImageView)
    }


    constructor(image: File):this(){
        arguments = Bundle().apply {
            putString(FILE_NAME_KEY, image.absolutePath)
        }
    }

}

调用B(修改)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
override fun getItem(position: Int): Fragment = UIFragmentPhoto(mediaList[position])
EN

回答 5

Stack Overflow用户

发布于 2019-11-01 01:56:22

Fragment的情况下:

根据定义默认构造函数的Fragment类在android.googlesource.com上的源代码,我们看到:

每个片段都必须有一个空的构造函数,因此可以在恢复其活动的状态时实例化它。强烈建议子类没有带有参数的其他构造函数,因为当片段被重新实例化时不会调用这些构造函数;相反,参数可以由调用方提供setArguments,然后由带有getArguments.Applications的片段检索,通常不应该实现构造函数。而更喜欢onAttach(上下文)。这是应用程序代码在准备使用片段的地方运行的第一个地方--片段实际上与其上下文相关联的位置。一些应用程序也可能希望实现onInflate来从布局资源中检索属性,但请注意,这是在附加片段时发生的。

鉴于上述原因,在非默认构造函数中添加Fragment是禁止的!

之后,使用setArgumentsgetArguments方法是避免添加额外构造函数的另一种方法。有问题的代码B,同时使用这两种方法。您应该使用其中之一,比如代码A。(因为当您将参数传递给构造函数时,可以在类中访问它。所以不需要[set/get]Arguments模式)

但是,如果我们想不使用参数重写代码B (免责声明:我强调这种方法不是真的),我们可以这样做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class UIFragmentPhoto internal constructor(private val image: File?) : Fragment() {

    constructor() : this(null)

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?,
                              savedInstanceState: Bundle?) = ImageView(context)

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        val resource = image ?: R.drawable.ic_photo
        Glide.with(view).load(resource).into(view as ImageView)
    }

}

一般而言:

我们都知道,对象是通过调用Java/Kotlin中类的构造函数方法创建的。例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
val obj = MyClass()

当您想要创建一个对象时,不需要将构造函数调用包装在另一个函数中,除非必须根据程序的性质更改对象的性质。因为它会导致额外的函数调用来创建一个没有任何优势的对象。

在根据程序性质变化对象的情况下,必须借助创造性的设计模式,提供更通用、更灵活的方法(如:工厂方法、抽象工厂模式等)。

结论:

  1. 当您处理从Fragment类创建对象时,应该使用代码--样式。(因为android.googlesource.com描述的原因)
  2. 当您处理从non-**Fragment类创建对象时,最好使用代码B**样式。(因为避免了没有优势的额外函数调用)
票数 4
EN

Stack Overflow用户

发布于 2019-10-27 19:26:27

不,这是低效的。代码B要求实例化片段的丢弃副本,这样就可以调用工厂方法来创建所需的实际片段。

票数 0
EN

Stack Overflow用户

发布于 2019-10-27 19:46:36

是用Kotlin在类中实例对象的好方法吗?

不怎么有意思。而且,这与Kotlin无关,它是一个语言不可知论的https://www.google.com/search?q=static%20factory%20method

如果以(B)方式初始化片段,则有三个问题:

1)很容易忘记在您的实例中调用“创建”:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
override fun getItem(position: Int): Fragment = UIFragmentPhoto() // Oops - bug

2)如果将create作为实例方法,则可以在现有片段上反复调用它:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
fun someFunction() {
    UIFragmentPhoto fragment = getExistingFragment()
    fragment.create() // Oops - just overwrote the fragment state
}

3)拥有一个“创建”已经创建的实例的方法只是让人困惑,也是初始化片段的一种非标准方法。这种静态/伴生方式的要点是,您有一个函数,它的任务是创建和初始化对象。

工厂方法还为您提供了在返回对象之前执行错误处理/验证的灵活性,并使您有机会创建一个完全不同的对象类型,该对象类型扩展/实现返回类型(如果您选择的话):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
companion object {
    fun create(arg: Int): UIFragmentPhoto {
        if (arg == 0) throw IllegalStateException("Wasn't expecting 0!")
        if (arg == 1) return FragmentThatExtendsUIFragmentPhoto()
        if (arg == 2) return UIFragmentPhoto()
    }
}
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58585384

复制
相关文章
AWS CPP S3访问COS
COS是完全兼容AWS S3的,项目中经常遇到客户直接使用AWS S3的相关SDK,来访问COS。
ictfox
2021/12/16
1.1K0
k8s中通过aws sdk访问s3遇到的坑
由于java使用命令行时可能会出现卡死现象,所以这里想使用aws提供的sdk来直接上传下载文件。 默认有两种方式,一种是程序中配置key:
一笠风雨任生平
2022/01/06
2.1K0
k8s中通过aws sdk访问s3遇到的坑
AWS CloudFront CDN + S3 CORS 跨域访问的问题
在研究 https://observablehq.com/ 的载入数据的时候,我们会发现如果你数据存在 S3 上使用 CloudFront 作为 CDN 的时候,你会发现数据库载入不进去。
HoneyMoose
2020/04/21
4.7K0
AWS CloudFront CDN + S3 CORS 跨域访问的问题
AWS S3 使用 travis 编译的时候提示错误 Aws::S3::Errors::PermanentRedirect
这是因为在我们的配置文件下 travis 将会把数据存储到 S3 的 us-east-2 存储区。
HoneyMoose
2020/12/22
6220
AWS S3 使用 travis 编译的时候提示错误 Aws::S3::Errors::PermanentRedirect
s3 aws 临时授权
https://docs.aws.amazon.com/zh_cn/AmazonS3/latest/userguide/AuthUsingTempSessionToken.html
周杰伦本人
2022/10/25
1.2K0
AWS S3 学习小结
1.首先,这个是AWS的开发资源使用文档:AWS开发文档,AWS官网 – S3教程
全栈程序员站长
2022/11/03
1.8K0
AWS S3 bucket 的 ACL 控制
https://www.ossez.com/t/aws-s3-bucket-acl/14175
HoneyMoose
2022/11/02
4720
「云网络安全」为AWS S3和Yum执行Squid访问策略
在本文中,我们将设置一个示例情况,展示如何使用开源Squid代理从Amazon虚拟私有云(VPC)中控制对Amazon简单存储服务(S3)的访问。首先,您将配置Squid以允许访问Linux Yum存储库。接下来,您将配置Squid,以限制对已批准的Amazon S3 bucket列表的访问。然后,您将配置Squid以根据URL直接流量,将一些请求发送到Internet网关(IGW),并将其他流量发送到虚拟专用网关(VGW)。最后,您将探索使Squid高度可用的选项。
架构师研究会
2021/01/06
3K0
「云网络安全」为AWS S3和Yum执行Squid访问策略
AWS EC2 在线扩容磁盘
对正在运行的生产服务器进行在线不停机扩容卷大小,在这个过程中,不影响已有的数据,不会对已有的磁盘做格式化,只单纯增加容量。
行 者
2023/10/20
6930
aws s3 java SDK使用[通俗易懂]
发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/179078.html原文链接:https://javaforall.cn
全栈程序员站长
2022/09/27
1.8K0
aws s3 java SDK使用[通俗易懂]
AWS CLI使用s3
aws CLI是什么东西,暂且先不去了解,目前的需求是s3. 我在Jenkins上创建一个bucket,然后申请access_key,然后就可以使用s3来存储数据了。也就是说,s3就是一个网盘。 1.安装CLI 文档:http://docs.aws.amazon.com/cli/latest/userguide/installing.html $ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
Ryan-Miao
2018/03/13
1.9K0
aws lambda python 上传s3
代码编写 Code writing 编写lambda函数 Write lambda functions 主要功能是查询数据库,在本地生成test.csv,而后上传至s3://test-bucket-dev桶,bthlt目录下. test.csv is generated locally and uploaded to s3://test-bucket-dev bucket,bthlt path. import pymysql import logging import boto3 from botocore
葫芦
2021/12/20
2.2K1
aws lambda python 上传s3
aws生产实践-8:解决私有子网下(nat网关)的EC2访问公网的问题
首先,AWS会分配一个VPC,在这个VPC下默认会有3个子网,我们建立的EC2实例都在这3个子网里。
千里行走
2021/11/10
1.7K0
aws生产实践-8:解决私有子网下(nat网关)的EC2访问公网的问题
LayerNorm 在 Transformers 中对注意力的作用研究
LayerNorm 一直是 Transformer 架构的重要组成部分。如果问大多人为什么要 LayerNorm,一般的回答是:使用 LayerNorm 来归一化前向传播的激活和反向传播的梯度。
deephub
2023/08/28
3040
LayerNorm 在 Transformers 中对注意力的作用研究
Linux使用root用户登录(AWS EC2)
在aws ec2上使用root用户登录 aws ec2默认是使用ec2-user账号登陆的,对很多文件夹是没有权限的。如何使用root账号执行命令就是一个问题了。解决办法如下: 1.根据官网提供的方法登录连接到EC2服务器(官网推荐widows用户使用PUTTY连接) 主机:是服务器的Public DNS 端口:22 2.创建root的密码,输入如下命令:sudo passwd root 3.然后会提示你输
小晟
2023/04/01
5.2K0
Linux使用root用户登录(AWS EC2)
What is AWS S3 and Why to use it?
AWS S3 is an object-based serverless storage service by Amazon web services which is much faster than hard drive file systems and block storage approaches to save data. Serverless means the storage is hosted on the cloud where you don’t have to configure the server with storage space restriction, it gets expanded dynamically with usage.
用户4822892
2020/01/22
6010
AWS S3 对象存储攻防
文章来源:火线Zone社区,链接:https://zone.huoxian.cn/d/907-aws-s3
火线安全
2022/03/01
3.5K0
AWS S3 对象存储攻防
如何使用亚马逊对象存储AWS S3 SDK访问腾讯云存储COS
COS 提供了 AWS S3 兼容的 API,因此当您的数据从 S3 迁移到 COS 之后,只需要进行简单的配置修改,即可让您的客户端应用轻松兼容 COS 服务。本文主要介绍不同开发平台的 S3 SDK 的适配步骤。在完成添加适配步骤后,您就可以使用 S3 SDK 的接口来访问 COS 上的文件了。
云存储
2020/05/26
4.2K0
如何使用goGetBucket扫描和发现AWS S3 Bucket
goGetBucket是一款针对AWS S3 Bucket的渗透测试与安全研究工具,在该工具的帮助下,广大研究人员可以快速扫描和发现AWS S3 Bucket。
FB客服
2023/08/08
2500
如何使用goGetBucket扫描和发现AWS S3 Bucket
AWS EC2 增加多个弹性 IP
一、 添加一个私有IP的 1. 实例->联网->管理私有IP地址 2. 分配新IP->是,更新 注意:记下刚生成的 私有 IP 二、把刚才生成的私有IP地址添加到网络接口 1. SSH连接到您的实例并
码农编程进阶笔记
2021/07/20
2K0

相似问题

通过角色和访问S3的AWS EC2 SSH

10

用于S3访问的AWS EC2 IAM角色不起作用

126

在terraform中授予aws ec2实例对aws secretsmanager的访问权限

119

AWS S3对象访问和编辑

14

AWS:提供对S3对象的有限和安全访问

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文