How to access a batch class of a class from a class in another package?

I have the following classes

Hello.java

package speak.hello;

import java.util.Map;

import speak.hi.CustomMap;
import speak.hi.Hi;

public class Hello {

    private Hi hi;

    Hello(Hi hi) {
        this.hi = hi;
    }

    public String sayHello() {
        return "Hello";
    }

    public String sayHi() {
        return hi.sayHi();
    }

    public Map<String, Object> getMap() {
        return hi.getMap();
    }

    public void clearMap() {
        hi.getMap().clear();
    }

    public void discardMap() {
        CustomMap map = (CustomMap) hi.getMap();
        map.discard();
    }

    public static void main(String[] args) {
        Hello hello = new Hello(new Hi());
        System.out.println(hello.sayHello());
        System.out.println(hello.sayHi());
        System.out.println(hello.getMap());
        hello.clearMap();
        System.out.println("--");
        hello.discardMap();
    }

}

Hi.java

package speak.hi;

import java.util.HashMap;
import java.util.Map;

public class Hi {
    public String sayHi() {
        return "Hi";
    }

    public Map<String, Object> getMap() {
        return new CustomMap<String, Object>();
    }
}

CustomMap.java

package speak.hi;

import java.util.HashMap;

public class CustomMap<K, V> extends HashMap<K, V> {
    private static final long serialVersionUID = -7979398843650044928L;

    public void discard() {
        System.out.println("Discarding Map");
        this.clearCache();
        this.clear();
    }

    @Override
    public void clear() {
        System.out.println("Clearing Map");
        super.clear();
    }

    private void clearCache() {
        System.out.println("Clearing Map");
    }
}

This works fine until I remove publicthe access specifier withCustomMap

package speak.hi;

import java.util.HashMap;

class CustomMap<K, V> extends HashMap<K, V> {
    private static final long serialVersionUID = -7979398843650044928L;

    public void discard() {
        System.out.println("Discarding Map");
        this.clearCache();
        this.clear();
    }

    @Override
    public void clear() {
        System.out.println("Clearing Map");
        super.clear();
    }

    private void clearCache() {
        System.out.println("Clearing Map");
    }
}

The compiler screams that

Type say.hi.CustomMap not displayed

Now, if I do not have the parameters to change speak.hi.CustomMap(third-party bank, etc.). Is there any way to use CustomMapout speak.hello.Hello?


One option that I know is to move speak.hello.Helloin speak.hi.Hello, since now in the package Hello, speak.hihe can access the private class of the classHi


Is there any other way to do this? Is reflection possible?


EDIT : Updated with more info on @StephenC

+5
10

default

public void discardMap() {
    //CustomMap map = (CustomMap) hi.getMap();
    //map.discard();
    try {
        Object o =hi.getClass().getMethod("getMap").invoke(hi);
        Method m = o.getClass().getMethod("discard");
        m.setAccessible(true);
        m.invoke(o);
    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}
+7

? ?

. Java, .

, private , :

  • Class.
  • Class.getDeclaredField(...) Field .
  • Field.setAccessible(true), .
  • Class.getField(object, Field), ( , ).

, , ... 'cos, . () Object - .


, . , :

  • , ,
  • ,
  • , ,
  • ( ) - .

( , , - , ).


, , ( ) , .

+8

. : . Hi , , , ?

+1

, API, .

? ?

, API. , , .

+1

, :

:

?

  • public: yes
  • protected: yes
  • default: yes
  • : no

?

  • public: yes
  • protected: no
  • default:
  • : no
+1

.

, , - speak.hello.Hello to speak.hi.Hello speak.hi Hi

package speak.hi;

public class Hello {

    private Hi hi;

    Hello(Hi hi) {
        this.hi = hi;
    }

    public String sayHello() {
        return "Hello";
    }

    public String sayHi() {
        return hi.sayHi();
    }

    public static void main(String[] args) {
        Hello hello = new Hello(new Hi());
        System.out.println(hello.sayHello());
        System.out.println(hello.sayHi());
    }

}
+1

, API, , , . , , . API - .

0

1- a.b.c.class1, class1 , . A.b.c.class2 1, class2 .

3- x.y.z.class3

1 3, - : -

baseclass= ( 2()). getClass(); , : -  baseClass.getSuperClass(); , .

, , .

0

Hi .

-1

, " " ( , ), NOT "private". , .

In addition, you CANNOT make any top-level class Private in Java.

And if you want to create a default class and still be able to access it in another package, then what will be the purpose of having access specifiers (modifiers)?

you need to either make the class public, or go to the same package.

-1
source

All Articles