关于Java:为什么要使用方法本地抽象的内部类

Why use method local abstract inner classes

可以与方法局部内部类一起使用的合法修饰符之一是抽象的。

例如:

1
2
3
4
5
6
public class Outer {
    public void method(){
        abstract class Inner{
        }
    }
}

在任何情况下你会使用这个吗?

在SCJP考试中你必须知道这一点。


这是一些无效的假设在原问题。这是一个合法的Java /有效的东西并不意味着它是东西,你要使用,或需要知道的。

I can’t召回案例,包含奇数角scjp的问题。

我想一个案例来了,我会在抽象类中被使用的一方法,但一切看起来很奇怪,和reeks of浴室设计。然而,这是一个例子,我的代码(代码来设计我的浴室安静)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
public class BatchExecutor {

    public static enum ResultNotification {
        JMS,
        MAIL
    };

    public Runnable createRunnable(ResultNotification type) {
        abstract class Prototype implements Runnable {
            public void run() {
                performBusinessLogic();
                publishResult();
            }

            abstract void publishResult();
        }

        switch (type) {
            case JMS: {
                return new Prototype() {
                    void publishResult() {
                        //Post result to JMS
                    }
                };
            }
            case MAIL: {
                return new Prototype() {
                    void publishResult() {
                        //Post result to MAIL
                    }
                };
            }
        }
        return null;
    }

    private void performBusinessLogic() {
        //Some business logic
    }

}


我只想在这案例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class Outer {
    public void method() {
        abstract class A {
            void bar(){}
            abstract void foo();
        }
        class B extends A {
            @Override
            void foo() {
            }
        }
        final class C extends A {
            @Override
            void foo() {
            }
        }
        A a1 = new B();
        A a2 = new C();
    }
}

但我真的不能想象。


Is there any situation where you would actually use this?

  • 让s<1>></子子在所有的情况下,你需要denote在抽象类中。

  • 让S<2>></子子在所有的情况下,你需要denote本地类。

  • 答案到你的问题可以通过检查发现子>1<S<></∩S子子子>2></

  • 相关问题:

    • 什么是福利做本地内部类提供的方法在Java?
    • 使用Java接口和抽象类[ ]

    clarification:我是两特征点(抽象类和本地类库)是完全正交的两个特点。当每个特征是有用的理解是关键的理解是,当他们是有用的在同一时间。


    在我看来,有没有真正使用这个特征。有一个abuses几尽,但有许多其他方式来写代码,你自己的浴室,不学习这一个。:D

    当你试图让在本地使用抽象类的方法,你需要定义至少两个混凝土的内部类的方法。在你结束一个均值法含至少三类方法变得相当长,这是好的和坏的风格。

    You have to know this for the SCJP exam.

    我真的希望的困境。方法本地内部类是已经足以被视为无用的一角(你应该知道他们的案例,但他们可能永远不会使用)。

    一个人问我,这在参加考试misunderstood Java激活。我不能访问本地和改性剂在一类(缺乏的方法。literals)这类不能从外面无论如何不可访问的。可以有finalabstract和改性剂,因为没有理由去禁止他们。原因是让他们有良好的正交性原则:astonishment)和最小二乘法。


    在这里你可以使用get http://java-questions.com / innerclass _ _ questions.html访谈

    它说

    内部类的方法被称为方法是在本地内部类。方法本地内部类只能被作为最终的或摘要。方法局部变量或全局类只能访问本地变量。如果最终被法

    你可以声明静态变量在IE中调用和使用他们的内部方法。

    编辑:摘要:为什么

    因为如果你不想创建一个内部类的对象。如果你在创建对象的方法,然后它会存储在堆和它的方法是不执行即使释放的条件可能是附近的外部对象的引用,这是当它返回的方法。

    所以它取决于你是否想要创建的实例或没有。如果你想创建,然后使用final修饰符。


    我认为在某些条件下缩小方法的范围是有用的。

    例如,我在单元测试中使用它。有时需要一个实用方法来减少测试的冗长性。但是这个实用方法可能与当前的测试数据集相关,并且不能在这个测试之外重用。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
      @Test
      public void facetting_is_impacted_by_filtering() {
        // given
        String userId ="cd01d6b08bc29b012789ff0d05f8e8f1";
        DocumentSolrClient client = solrClientsHolder.getDocumentClient(userId);
        //
        final SolrDocument doc1 = createDocument(userId);
        doc1.setAuthorName("AuthorName1");
        doc1.setType("Type1");
        doc1.setUserTags(Arrays.asList("UserTag1","UserTag1bis","UserTag1bisbis"));
        doc1.setSenderTags(Arrays.asList("SenderTag1","SenderTag1bis"));
        doc1.setCreationDate( new Date(EnumDateRange.CURRENT_DAY.getBegin().getTime()+1000) );
        doc1.setLocation(DocumentLocation.INBOX);
        client.index(doc1);
        //
        final SolrDocument doc2 = createDocument(userId);
        doc2.setAuthorName("AuthorName2");
        doc2.setType("Type2");
        doc2.setUserTags(Arrays.asList("UserTag2"));
        doc2.setSenderTags(Arrays.asList("SenderTag2"));
        doc2.setCreationDate( new Date(1000) ); // cree il y a tres longtemps
        doc2.setLocation(DocumentLocation.SAFE);
        client.index(doc2);
        //
        final List<DateRange> facettedRanges = Arrays.<DateRange>asList(
                EnumDateRange.CURRENT_DAY,
                EnumDateRange.CURRENT_YEAR,
                EnumDateRange.BEFORE_CURRENT_YEAR
        );
        class TestUtils {
          ApiSearchRequest baseFacettingRequest(String userId) {
            ApiSearchRequest req = new ApiSearchRequest(userId);
            req.setDocumentTypeFacets(true);
            req.setSenderNameFacets(true);
            req.setSenderTagsFacets(true);
            req.setUserTagsFacets(true);
            req.addDateCreationFacets(facettedRanges);
            return req;
          }
          void assertDoc1FacettingResult(ApiSearchResponse res) {
            assertThat(res.getDocuments().size()).isEqualTo(1);
            assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
            assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
            assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(2);
            assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(3);
            assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1),facettedRanges) );
          }
          void assertDoc2FacettingResult(ApiSearchResponse res) {
            assertThat(res.getDocuments().size()).isEqualTo(1);
            assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(1);
            assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(1);
            assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(1);
            assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(1);
            assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc2),facettedRanges) );
          }
        }
        TestUtils utils = new TestUtils();
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // when
        ApiSearchRequest req = utils.baseFacettingRequest(userId);
        ApiSearchResponse res = documentSearchService.search(req);
        // then
        assertThat(res.getDocuments().size()).isEqualTo(2);
        assertThat(res.getDocumentTypeFacets().get().getCounts()).hasSize(2);
        assertThat(res.getSenderNameFacets().get().getCounts()).hasSize(2);
        assertThat(res.getSenderTagsFacets().get().getCounts()).hasSize(3);
        assertThat(res.getUserTagsFacets().get().getCounts()).hasSize(4);
        assertThat(res.getDateCreationFacets().get().getCounts()).isEqualTo( computeExpectedDateFacettingResult( Arrays.asList(doc1,doc2),facettedRanges) );
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // when
        req = utils.baseFacettingRequest(userId);
        req.addLocation(DocumentLocation.SAFE);
        res = documentSearchService.search(req);
        // then
        utils.assertDoc2FacettingResult(res);
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // when
        req = utils.baseFacettingRequest(userId);
        req.addUserTag("UserTag1");
        res = documentSearchService.search(req);
        // then
        utils.assertDoc1FacettingResult(res);
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // when
        req = utils.baseFacettingRequest(userId);
        req.addSenderTag("SenderTag2");
        res = documentSearchService.search(req);
        // then
        utils.assertDoc2FacettingResult(res);
        /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        // when
        req = utils.baseFacettingRequest(userId);
        req.setDocumentType("Type1");
        res = documentSearchService.search(req);
        // then
        utils.assertDoc1FacettingResult(res);
      }

    在这个真实的例子中,我本可以做一个常规的内部类,但是有人可能会在其他测试中尝试重用它,而它并不是为之设计的。

    顺便说一下,您将注意到直接在实用程序类内部的测试中"捕获"数据集构建的能力。使用常规的内部类,如果不在测试外部创建特定于测试的数据集,它也无法工作…因此,您最终会得到许多与其他测试共享的东西,而它们只被一个测试使用(应该被使用)。

    最后,我不认为允许降低可见性的功能是无用的。

    您可以构建一个完全可以工作的应用程序,而完全不使用封装,并且可以争论同样的事情,说私有修饰符是无用的…

    但是是的,私有修饰符肯定比方法局部内圆更有用;)


    查看本页标题为"内部类层次结构"的部分。

    要点是,您可以将内部类视为需要重写/实现的另一个抽象成员。我不一定同意这一点(我可能会单独定义内部类),但我在野外见过类似的事情。

    以下是他们的示例代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    public abstract class BasicMonitorScreen {
       private Dimension resolution;

       public BasicMonitorScreen(final Dimension resolution) {
          this.resolution = resolution;
       }

       public Dimension getResolution( ) {
          return this.resolution;
       }

       protected abstract class PixelPoint {
          private int x;

          private int y;

          public PixelPoint(final int x, final int y) {
             this.x = x;
             this.y = y;
          }

          public int getX( ) {
             return x;
          }

          public int getY( ) {
             return y;
          }
       }
    }

    public class ColorMonitorScreen extends BasicMonitorScreen {
       public ColorMonitorScreen(final Dimension resolution) {
          super(resolution);
       }

       protected class ColorPixelPoint extends PixelPoint {
          private Color color;
          public ColorPixelPoint(final int x, final int y, final Color color) {
             super(x, y);
             this.color = color;
          }

          public Color getColor( ) {
             return this.color;
          }
       }
    }

    没有,有没有好用的抽象类(或类内部方法在通用)。

    如果它只会是特别的意义,特别是法不需要IT类和不那么热情。有一次这样的情况也许是发生在你写trillions)方法。


    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    package dto;

    public class Outer {

        public void method(int x, int y){
            abstract class Inner{
                abstract void performAction(int x,int y);
            }
            class InnnerA extends Inner{

                @Override
                void performAction(int x,int y) {
                    int z =x+y;
                    System.out.println("addition :" + z);

                }

            }
            class InnnerB extends Inner{

                @Override
                void performAction(int x,int y) {
                    System.out.println("multiply :"+x*y);

                }

            }
            Inner inner1 = new InnnerA();
            inner1.performAction(x,y);
            Inner inner2 = new InnnerB();
            inner2.performAction(x,y);
        }
        public static void main(String args[]){
            Outer outer = new Outer();
            outer.method(10,20);
        }
    }

    你可以使用它的样本。


    唯一真实的是我可以想象使用节点的数据结构

    这样你可以differentiate方法从哨兵节点和数据节点可以正常工作在递归算法的手机和你的不为零的每一次检查